为什么这在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实际上被翻译为直接访问backing字段(但我会仔细检查)。注意,相同的规则已经应用于事件:给定
公共事件事件处理程序X
X
可以引用事件的
add
/
remove
访问器,也可以引用事件的backing字段。@hvd您所说的setter调用实际上是如何实现的。我所说的
X
总是指属性,这在语言层面上是正确的。但就实际运行的代码而言,这当然不是真的。我不认为我们在这里有分歧……我是说,这家酒店甚至没有一个setter。甚至不是私人的。这意味着它可以工作的唯一方法是直接引用支持字段。我现在确实查过了,这正是发生的事情。但是,事实上,也许你说得有道理。据我所知,目前还没有C#6语言规范,目前的行为可以用多种不同的方式来描述,以实现相同的结果。我们还不知道语言规范最终会使用哪种描述。谢谢,我明白了,但是有没有方法通过引用传递属性,例如使用委托?@Nostradamus在某个点上,您必须在某个函数中写入
out X
。您可以尝试将此函数隐藏在委托内部深处,等等。但最终,当您真正调用
TryParse
时,它将需要一个局部/成员变量,因为
out
/
ref
参数实际上是作为内存地址传递的,编译器不会获取属性的地址。