在C#中存储对象的引用

Jac*_*nds 5 .net c#

我想知道如何在.net中存储对象的引用.

也就是说,我想要类似下面的代码(注意,当然,以下代码可能与实际操作方式有关):

class Test
{
    private /*reference to*/ Object a;
    public Test(ref int a)
    {
        this.a = a;
        this.a = ((int)this.a) + 1;
    }
    public Object getA() { return this.a; }
}
/*
 * ...
 */
static void Main(string[] args)
{
    int a;
    a=3;
    Test t = new Test(ref a);
    Console.WriteLine(a);
    Console.WriteLine(t.getA());
    Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)

要产生以下输出:

4
4
Run Code Online (Sandbox Code Playgroud)

理想情况下,我想在没有围绕整数编写包装类的情况下执行此操作.

换句话说,我想我想要.Net中的指针.

Eri*_*ert 36

您不能在.NET,period中存储对变量的引用.您可以存储对象的引用,但不能存储对变量的引用.

原因是如果允许存储对任意变量的引用,那么您可以存储对局部变量的引用.如果可以存储对局部变量的引用,那么运行时不能使用在短期内存池(即堆栈)上存储局部变量的优化.

现在,即使你可以这样做,你描述的操作也不是因为其他原因而不是类型安全的.你有一个(命名非常糟糕的)字段变量"a"类型为"对象变量的引用"和一个(非常严重且容易混淆的)局部变量"a"类型为"引用int变量".即使你可以存储对变量的引用,在"引用对象变量"类型的东西中存储对int变量的引用也没有任何意义,因为这两种类型在逻辑上是不兼容的.您可以对它们执行的操作是不同的; 对象变量的引用可以写入一个字符串; 对int变量的引用不能.

也许我是误会,但不会将上面的整数变量装入一个可以存储为参考的对象中?

您对引用变量的对象的引用感到困惑.令人困惑的是,我们对两个不同的东西使用相同的术语.

是的,拳击将值类型(如int)转换为引用类型,如object.对于变量的引用,这绝对没有任何意义.

当您对变量进行引用时,您正在为该变量创建别名.当你说

void M(ref int y) { y = 123; }
...
int x = 0;
M(ref x);
Run Code Online (Sandbox Code Playgroud)

你说的是"x和y是同一个变量的两个不同的名字".

现在,如果您想要做的是代表"我已经捕获了一个变量并且我希望能够读取和写入它"的概念,那么请使用委托:

class Ref<T>
{
    private Func<T> getter;
    private Action<T> setter;
    public Ref(Func<T> getter, Action<T> setter)
    {
        this.getter = getter;
        this.setter = setter;
    }
    public T Value
    {
        get { return getter(); }
        set { setter(value); }
    }
}
...
int abc = 123;
var refabc = new Ref<int>(()=>abc, x=>{abc=x;});
... now you can pass around refabc, store it in a field, and so on
refabc.Value = 456;
Console.WriteLine(abc); // 456
Console.WriteLine(refabc.Value); // 456
Run Code Online (Sandbox Code Playgroud)

合理?


Mar*_*tos 10

C#没有类似于C++的引用变量的概念int& a.有解决方法.一个是使用闭包:

class Test
{
    private Func<int> get_a;
    private Action<int> set_a;
    public Test(Func<int> get_a, Action<int> set_a)
    {
        this.get_a = get_a;
        this.set_a = set_a;
        this.set_a(this.get_a() + 1);
    }
    public Object getA() { return this.get_a(); }
}
/*
 * ...
 */
static void Main(string[] args)
{
    int a;
    a=3;
    Test t = new Test(() => a, n => { a = n; });
    Console.WriteLine(a);
    Console.WriteLine(t.getA());
    Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)

我不在VS面前,所以请原谅任何令人尴尬的失礼.

  • +1,不是我在生产代码中使用的东西; 但可爱 (2认同)