2

有没有办法将一个变量设置为一个对象并让另一个变量始终等于前一个?

var x = new object();
var y = [synonym of x];
x = null; // then y = null as well

我不认为这存在。

所以我经常使用数组来保存“引用”。

var x = new object[] { new object() };
var y = x;
x[0] = null; // then y[0] = null as well

但是感觉有点鸡肋。

4

5 回答 5

5

如果您真的需要这样做,您可以执行以下操作,但我认为它仍然很蹩​​脚(:

class RefHolder<T>
{
    public RefHolder(T value)
    {
        Value = value;
    }

    public T Value { get; set; }
}

用法

var o1 = new RefHolder<object>(new object());
var o2 = o1;
o2.Value = null; // now o1.Value is null too
于 2013-06-28T12:08:40.607 回答
3

您可以这样做,但您必须付出的代价是使用未记录的关键字/功能。它们很久以前就在那里,可能不会改变或消失,但是......

它会使您的代码阅读起来更加复杂(如果语言本身支持它可能会很有用),但它是双向的,您可以在原始对象周围移动,更改也将始终反映到您的“参考”中。它与 Mehmet Ataş 的答案不同,因为您可以将原始对象传递给另一个函数,并且更改也会传播到您的同义词。它们有限制(它们不能用于类字段),但它们适用于参数和局部变量。

您需要的是 a TypedReference,它包含对另一个变量的引用,然后如果您为其分配一个新值,您将更改原始变量。如果有一天他们认为这是一个很好的功能,这在理论上可以为同义词打开大门。

让我们看一个例子:

var text = "initial value";
var synonym = __makeref(text);

现在synonym是对文本的引用(请注意,它是对text它所持有的值的引用,而不是对它的引用)。要从TypedReference您使用的 a 中获取原始值,__refvalue如下所示:

Console.WriteLine(__refvalue(synonym, string));

它们具有相同的值:

Debug.Assert(__refvalue(synonym, string) == text);

现在让我们将文本更改为新值:

text = "second value";
Debug.Assert(__refvalue(synonym, string) == text);

甚至相反:

__refvalue(synonym, string) = "third value"; // <---
Debug.Assert(__refvalue(synonym, string) == text);

最后让我们在另一个函数中修改原始变量(不知道引用它会看到一个普通变量):

void ChangeIt(ref string value) { value = "another value"; }

ChangeIt(ref text);
Debug.Assert(__refvalue(synonym, string) == text);

所有这些工作也将重视类型。请注意,这会为变量创建同义词,而不是别名(您可以将它们想象为安全指针 - 在引用类型的情况下指向指针)。让我们试试这个:

void foo1()
{
    string text = "ABC";
    foo2(text);

    // text holds the original value "ABC"
    // not the value modified in foo2
}

void foo2(string value)
{
   value = "123";
   var synonym = __makeref(value);
   __refvalue(value, string) = "456";

   // both value and synonym holds "456";
}
于 2013-06-28T12:58:42.587 回答
1

好吧,您基本上是在描述 C++ 引用(或 C 指针)。这也可以在 C# 中完成,但除非绝对需要,否则您真的不想这样做。

unsafe static void Main(string[] args)
    {
        int a = 5;

        int *b = &a;
        *b = 0;

        Console.WriteLine(a);
    }

这将输出0到控制台。

您可以在 MSDN 上的Unsafe Code and Pointers文章中阅读有关不安全代码的更多信息。

于 2013-06-28T12:50:28.890 回答
0

这取决于。.NET 包含引用类型和值类型。值类型是所有基本类型,int、bool 等。加上字符串。引用类型是其他所有内容,包括您为自己创建的任何内容。

因此,例如,值类型...

int a = 3;
int b = a;
b = 5;
// a is still 3

虽然有参考

class Mine {
  public int A { get; set; }
}
Mine A = new Mine() { A = 3; }
Mine B = A;
B.A = 5;
// A.A is now 5.
于 2013-06-28T12:10:30.073 回答
-1

你可以像这样分配

var parentObject={};

parentobject['child1']="test1";
parentobject['child2']="test2";
parentobject['child3']="test3";

控制台.log(父对象);

你得到以下输出

对象{child1="test1",child2="test2",child2="test2"}

于 2013-06-28T12:19:09.463 回答