是否存在同义词?

时间:2013-06-28 12:00:08

标签: c# keyword

有没有办法让变量设置为一个对象,另一个变量总是等于前者?

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

但感觉有点蹩脚。

5 个答案:

答案 0 :(得分: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

答案 1 :(得分:3)

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

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

您需要的是TypedReference,它将引用保存到另一个变量,然后如果您为其指定一个新值,您将更改原始变量。这在理论上可以打开同义词的大门,如果有一天他们会认为它是一个很好的特征包括在内。

让我们看一个例子:

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

现在synonym是对文字的引用(请注意它是对text的引用,而不是它所持有的值)。要从TypedReference获取原始值,请使用__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";
}

答案 2 :(得分: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文章中阅读有关不安全代码的更多信息。

答案 3 :(得分: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.

答案 4 :(得分:-1)

你可以像

一样
var parentObject={};

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

之后

  

的console.log(parentObject);

你得到以下输出

<强>对象{child1 = “测试1”,的child2 = “test2的”,的child2 = “test2的”}