例如:
int? qID= null;
answer.QuestionID = int.TryParse(lblID.Text, out qID.Value) ? qID : null; //Error: Property or Indexer may not be passed as an out ot ref parameter.
从microsoft文档中可以看出:
“作为out参数传递的变量不需要初始化。但是,必须在方法返回之前为out参数赋值。”
然后:
“属性不是变量,不能作为out参数传递。
那么基础.net平台设计中的原因是什么禁止通过out设置对象的属性? out的值也不一定是参考对象 - 使用值类型完全合法。那为什么不呢?
答案 0 :(得分:15)
这在VB中有效,但在C#中无效... VB有效地为您创建一个临时局部变量,调用传入局部变量的方法作为参数,然后使用局部变量的值设置属性。 C#通常不会为你隐藏那类东西。
该方法本身需要变量作为out
参数。它必须有一个存储位置,它只能写入值。不是属性,也不是它需要调用的任何东西:只是一个存储位置。财产不满足该要求。因此,方法中的编译器无法做到这一点。
因此,编译器必须根据VB使用临时变量伪造它,或者根据C#禁止它。我个人更喜欢C#方法 - 否则它看起来好像每次方法为out参数赋值时,属性都会被设置 - 当然不是这样。
答案 1 :(得分:10)
属性只是一对名为get_Something
和set_Something
的函数
out
参数引用字段或变量;传递一对函数没有任何意义。
VB.Net can pass properties as ByRef
parameters;编译器生成一个临时变量,并在调用方法后重新赋予变量proeprty。
然而,即使VB.Net无法处理您的情况,因为Nullable<T>.Value
属性是只读的。
答案 2 :(得分:2)
int qID;
if (int.TryParse(lblID.Text, out qID))
{
answer.QuestionID = qID;
}
else
{
answer.QuestionID = null;
}
这是实际的实现:
[System.Security.SecuritySafeCritical] // auto-generated
internal unsafe static Boolean TryParseInt32(String s, NumberStyles style, NumberFormatInfo info, out Int32 result) {
Byte * numberBufferBytes = stackalloc Byte[NumberBuffer.NumberBufferBytes];
NumberBuffer number = new NumberBuffer(numberBufferBytes);
result = 0;
if (!TryStringToNumber(s, style, ref number, info, false)) {
return false;
}
if ((style & NumberStyles.AllowHexSpecifier) != 0) {
if (!HexNumberToInt32(ref number, ref result)) {
return false;
}
}
else {
if (!NumberToInt32(ref number, ref result)) {
return false;
}
}
return true;
}
答案 3 :(得分:2)
因为属性是编译器生成的get
和set
方法的语法糖。
答案 4 :(得分:2)
属性只是一对访问器方法的语法糖,所以你在这里实际做的是调用一个方法并将结果值作为参考传递。显然,这个值不是变量,所以它不能被绑定。
考虑具有属性Foo
的类型Bar
;将该属性用作out
参数基本上类似于:
Foo foo = new Foo();
SomeFunction(out foo.get_Bar());
显然,无法将值分配给foo.get_Bar()
!