为什么属性不能作为out参数传递?

时间:2021-01-17 21:03:54

For example:

例如:

    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.

From microsoft documentation it says that:

从微软的文档中可以看出:

"A variable passed as an out argument need not be initialized. However, the out parameter must be assigned a value before the method returns."

作为out参数传递的变量不需要初始化。但是,在方法返回之前,必须给out参数赋值。

and then:

然后:

"A property is not a variable and cannot be passed as an out parameter.

属性不是变量,不能作为out参数传递。

So what was the reasoning in the underlying .net platform design to prohibit from setting a property of an object via the out? The value of out does not have to be a reference object either - totally legit to use a value type. So why not?

那么,在底层的。net平台设计中,有什么理由禁止通过out来设置对象的属性呢?out的值不一定是一个引用对象——完全合法地使用值类型。所以为什么不呢?

5 个解决方案

#1


14  

This is valid in VB, but not in C#... VB effectively creates a temporary local variable for you, calls the method passing in the local variable as the argument, and then sets the property with the value of the local variable. C# doesn't usually hide that sort of thing for you.

这在VB中是有效的,但在c#中是无效的。VB有效地为您创建了一个临时的局部变量,调用在局部变量中传递的方法作为参数,然后用局部变量的值设置属性。c#通常不会为你隐藏这类事情。

The method itself needs a variable as the out parameter. It's got to have a storage location it can just write values to. Not a property, not anything it needs to invoke: just a storage location. A property doesn't satisfy that requirement. So there's nothing that can be done by the compiler in the method to allow this.

该方法本身需要一个变量作为out参数。它必须有一个存储位置它可以将值写入。不是属性,也不是它需要调用的任何东西:只是一个存储位置。一个属性不能满足这个要求。所以在这个方法中编译器不能做任何事情。

So either the compiler has to fake it with a temporary variable, as per VB, or disallow it, as per C#. Personally I prefer the C# approach - otherwise it looks as if each time the method assigned a value to the out parameter, the property would be set - which certainly isn't the case.

因此,编译器必须用一个临时变量来伪造它,就像每个VB一样,或者不允许它,就像每个c#一样。个人而言,我更喜欢c#方法——否则它看起来就像每次分配一个值到out参数的方法一样,属性将被设置——当然不是这样。

#2


9  

A property is just a pair of functions named get_Something and set_Something.
An out parameter takes a reference to a field or a variable; it wouldn't make any sense to pass a pair of functions.

属性只是一对名为get_Something和set_Something的函数。out参数引用一个字段或一个变量;传递一对函数是没有意义的。

VB.Net can pass properties as ByRef parameters; the compiler generates a temporary variable and re-assigns the proeprty to the variable after calling the method.

VB。Net可以作为ByRef参数传递属性;编译器生成一个临时变量,并在调用该方法后将proeprty重新分配给变量。

However, even VB.Net cannot handle your case, because the Nullable<T>.Value property is read-only.

然而,即使VB。Net不能处理您的情况,因为Nullable 。价值属性是只读的。

#3


2  

Because a property is syntactic sugar for a get and a set method that are generated by the compiler.

因为属性是get的语法糖和由编译器生成的set方法。

#4


2  

Properties are just syntactic sugar for a pair of accessor methods, and so what you're actually doing here is calling a method and passing the resulting value as a reference. Clearly this value isn't a variable and so it can't be bound to.

属性只是一对访问器方法的语法糖,因此您实际上在这里做的是调用一个方法并将结果值作为引用传递。显然,这个值不是一个变量,所以它不能被绑定到。

Consider a type Foo with a property Bar; using that property as an out parameter is essentially analogous to this:

考虑一个带有属性栏的Foo类型;使用该属性作为out参数,本质上类似于:

Foo foo = new Foo();
SomeFunction(out foo.get_Bar());

Obviously, a value can't be assigned to foo.get_Bar()!

显然,一个值不能分配给foo.get_Bar()!

#5


2  

int qID;

if (int.TryParse(lblID.Text, out qID))
{
  answer.QuestionID =  qID;
}
else
{
  answer.QuestionID = null;
}

here is the actual implementation:

这里是实际的实现:

[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; 
    }

#1


14  

This is valid in VB, but not in C#... VB effectively creates a temporary local variable for you, calls the method passing in the local variable as the argument, and then sets the property with the value of the local variable. C# doesn't usually hide that sort of thing for you.

这在VB中是有效的,但在c#中是无效的。VB有效地为您创建了一个临时的局部变量,调用在局部变量中传递的方法作为参数,然后用局部变量的值设置属性。c#通常不会为你隐藏这类事情。

The method itself needs a variable as the out parameter. It's got to have a storage location it can just write values to. Not a property, not anything it needs to invoke: just a storage location. A property doesn't satisfy that requirement. So there's nothing that can be done by the compiler in the method to allow this.

该方法本身需要一个变量作为out参数。它必须有一个存储位置它可以将值写入。不是属性,也不是它需要调用的任何东西:只是一个存储位置。一个属性不能满足这个要求。所以在这个方法中编译器不能做任何事情。

So either the compiler has to fake it with a temporary variable, as per VB, or disallow it, as per C#. Personally I prefer the C# approach - otherwise it looks as if each time the method assigned a value to the out parameter, the property would be set - which certainly isn't the case.

因此,编译器必须用一个临时变量来伪造它,就像每个VB一样,或者不允许它,就像每个c#一样。个人而言,我更喜欢c#方法——否则它看起来就像每次分配一个值到out参数的方法一样,属性将被设置——当然不是这样。

#2


9  

A property is just a pair of functions named get_Something and set_Something.
An out parameter takes a reference to a field or a variable; it wouldn't make any sense to pass a pair of functions.

属性只是一对名为get_Something和set_Something的函数。out参数引用一个字段或一个变量;传递一对函数是没有意义的。

VB.Net can pass properties as ByRef parameters; the compiler generates a temporary variable and re-assigns the proeprty to the variable after calling the method.

VB。Net可以作为ByRef参数传递属性;编译器生成一个临时变量,并在调用该方法后将proeprty重新分配给变量。

However, even VB.Net cannot handle your case, because the Nullable<T>.Value property is read-only.

然而,即使VB。Net不能处理您的情况,因为Nullable 。价值属性是只读的。

#3


2  

Because a property is syntactic sugar for a get and a set method that are generated by the compiler.

因为属性是get的语法糖和由编译器生成的set方法。

#4


2  

Properties are just syntactic sugar for a pair of accessor methods, and so what you're actually doing here is calling a method and passing the resulting value as a reference. Clearly this value isn't a variable and so it can't be bound to.

属性只是一对访问器方法的语法糖,因此您实际上在这里做的是调用一个方法并将结果值作为引用传递。显然,这个值不是一个变量,所以它不能被绑定到。

Consider a type Foo with a property Bar; using that property as an out parameter is essentially analogous to this:

考虑一个带有属性栏的Foo类型;使用该属性作为out参数,本质上类似于:

Foo foo = new Foo();
SomeFunction(out foo.get_Bar());

Obviously, a value can't be assigned to foo.get_Bar()!

显然,一个值不能分配给foo.get_Bar()!

#5


2  

int qID;

if (int.TryParse(lblID.Text, out qID))
{
  answer.QuestionID =  qID;
}
else
{
  answer.QuestionID = null;
}

here is the actual implementation:

这里是实际的实现:

[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; 
    }