为什么这在C#中不合法?
这不管用为什么这在C#中不合法?,c#,c#-6.0,C#,C# 6.0,这不管用 public class Foo { private int X { get; } public Foo(string s) { int.TryParse(s, out X); } } 但这是可行的: public class Foo { private int X { get; } public Foo(string s) { int x; int.TryParse(s, out x);
public class Foo {
private int X { get; }
public Foo(string s) {
int.TryParse(s, out X);
}
}
但这是可行的:
public class Foo {
private int X { get; }
public Foo(string s) {
int x;
int.TryParse(s, out x);
X = x;
}
}
由于不需要初始化out
参数,两者之间的区别是什么。为什么该属性不能作为out参数传递?我假设这是C#6.0,因为您有一个只包含get
的属性
它不起作用,因为属性不能通过引用传递。在C++中,使用一个函数<代码> > REF int < /> >或<代码> int 参数,就像C++中的<代码> int和< />代码的函数。
但是int
属性不仅仅是某个地址的int
。属性可以在get
和set
中运行它想要的任何代码。该语言不应将自动实现的属性视为特殊属性
如果我像下面这样写代码呢
public class Foo {
private int X {
get { return 0; }
set { }
}
public Foo(string s) {
int.TryParse(s, out X);
}
}
根本没有任何int
的地址可以传递到TryParse
。关于代码是否允许的规则不允许查看get
和set
实现内部
请注意,这样做很好:
public class Foo {
private int X;
public Foo(string s) {
int.TryParse(s, out X);
}
}
当您使用
out
时,它实际上是一个传递给您调用的函数的内存地址。属性不是一个变量,而是一个函数,您不能获取它的地址,因此不能传递属性来代替out
参数
成员变量(或局部变量)占用内存,编译器可以获取它们的地址并传递它,这样它就可以处理变量而不是属性。您的属性不需要设置
?因为属性会在内部重写为方法调用get_X()
。out参数只能是变量或字段。@WaiHaLee这是一个新的C#6功能。不,它不需要集
。我想你是说C#6.0(或者只要C#6也可以)。但是X=X代码>不分配给属性,它直接分配给属性的支持字段。如果X
可以根据上下文引用属性或支持字段,则int.TryParse(s,out X)
可以正常工作。根本不是。@hvd你说得对,我对ASP.NET 5感到困惑“X
可以根据上下文引用属性或支持字段。”-它不能引用任何一个;它总是指属性。那么你如何解释X=X代码>编译?X
是否有在构造函数之外无法访问的私有setter?它不是,X=X至少根据Roslyn的文档,code>实际上被翻译为直接访问backing字段(但我会仔细检查)。注意,相同的规则已经应用于事件:给定公共事件事件处理程序X
,X
可以引用事件的add
/remove
访问器,也可以引用事件的backing字段。@hvd您所说的setter调用实际上是如何实现的。我所说的X
总是指属性,这在语言层面上是正确的。但就实际运行的代码而言,这当然不是真的。我不认为我们在这里有分歧……我是说,这家酒店甚至没有一个setter。甚至不是私人的。这意味着它可以工作的唯一方法是直接引用支持字段。我现在确实查过了,这正是发生的事情。但是,事实上,也许你说得有道理。据我所知,目前还没有C#6语言规范,目前的行为可以用多种不同的方式来描述,以实现相同的结果。我们还不知道语言规范最终会使用哪种描述。谢谢,我明白了,但是有没有方法通过引用传递属性,例如使用委托?@Nostradamus在某个点上,您必须在某个函数中写入out X
。您可以尝试将此函数隐藏在委托内部深处,等等。但最终,当您真正调用TryParse
时,它将需要一个局部/成员变量,因为out
/ref
参数实际上是作为内存地址传递的,编译器不会获取属性的地址。