抱歉,这是一个基本问题,我找不到答案。
我必须在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#会删除创建引用成员变量的功能?
答案 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.List
和y.List
是同一个对象,至少在你为其中一个分配一个新对象之前 - C#引用,不像C ++引用(至少从C ++ 98开始;我自2006年以来没有跟上)是“可重新绑定的”。
执行此操作的方法是编写一个具有int
属性的简单类,并共享对该实例的引用。 where T : struct
将T
限制为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>
而不创建昂贵的副本。