如何在C#中创建引用成员变量,就像在C ++中一样

时间:2017-05-31 17:39:10

标签: c# windows pointers visual-studio-2015 reference

抱歉,这是一个基本问题,我找不到答案。

我必须在C#中编写一些代码,我需要创建一个作为引用的类成员变量。

在C ++中,这段代码将是

public class MyClass
{
     MyClass(int& m_var): mVar(m_var){}
     int& mVar;
}

但是我似乎无法在C#

中这样做

我可以使用

创建一个带参考参数的构造函数
MyClass(ref int m_var)

但我无法使用

创建引用成员变量
class MyClass
{
     MyClass(ref int m_var)
     {
          mVar = m_var;
     }
     ref int mVar;
}

因为行:

     ref int mVar;

给我错误:'Invalid Token 'ref' in class, struct, or interface member declaration.

这是为什么?为什么C#会删除创建引用成员变量的功能?

1 个答案:

答案 0 :(得分:1)

  

int只是这里另一个类的占位符

哇那里! int不仅仅是“另一个阶级”。 int是值类型。你不能有一个引用它的字段。您可以拥有ref参数。在C#7中,您可以获得ref返回和本地,但仍然不是字段。

在CLR中,int与我们在这里谈论的区域中的类别截然不同。 x是我们称之为“堆栈”的int,因为我不想查看它们是如何实现它的。在C中,我似乎记得将其描述为堆栈变量:

int x = 0;

List<T>是一个班级。 y,这里是一个“堆栈变量”,它是对“堆”上对象的可重新引用的引用:

var y = new List<int>();

如果您正在讨论分享对引用类型的引用 - 任何class - 在C#中很容易:它总是一个引用。

public class C {
    //  x is passed by value. It is the value of a reference. Seriously, it is. 
    public C(List<String> x) {
        List = x;
    }
    public List<String> List { get; set; }
}

...

var list = new List<String>();
var x = new C(list);
var y = new C(list);

x.Listy.List是同一个对象,至少在你为其中一个分配一个新对象之前 - C#引用,不像C ++引用(至少从C ++ 98开始;我自2006年以来没有跟上)是“可重新绑定的”。

执行此操作的方法是编写一个具有int属性的简单类,并共享对该​​实例的引用。 where T : structT限制为struct而不是类。在CLR-land中,这意味着“价值类型”而不是“参考类型”。

public class Reference<T> where T : struct
{
    public Reference(T t) {
        Value = t;
    }

    public T Value { get; set; }
}

class MyClass
{
     MyClass(Reference<int> ref)
     {
          _ref = ref;
     }
     Reference<int> _ref;
}
  

为什么C#会删除创建引用成员变量的功能?

他们没有“把它带走”;他们没有绑架一个婴儿C ++编译器并削减它的脚趾。他们只是认为在C#中做到这一点并不是一个好主意,而且他们是正确的。 C#不是C而且它不是C.丹尼斯·里奇设计的C被Ken Thompson这样的人使用; Anders Hejlsberg明确地设计了C#供我们其他人使用,他们更容易混淆。

This is built deeply into .NET

  

然而,CLR类型系统不允许作为其他变量别名的字段

(这是一篇旧文章; C#7现在确实支持CLR一直支持的ref的额外用法)。

新的C#程序员已经在ref和引用类型方面遇到了足够的麻烦。就在最近,我在这里看到一个问题中的代码:

public void F(ref List<int> x) { ... }

编写该代码的人只是想传递List<int>而不创建昂贵的副本。