C#:函数中的'out'out'参数是对象属性/变量吗?
例如:
我可以按如下方式调用函数:
someFunction(x, y, out myObject.MyProperty1)
答案 0 :(得分:6)
属性是[一对get和set]方法,它们具有可爱的语法,用于调用它们使它们看起来像字段。
Out参数可以是对字段或基于堆栈的“字段”(即本地)的引用。
这种差距的弥合通常不是由语言解决的(并且肯定不是由CLR和IL模型直接解决)。 (关于VB技巧参考的@Heinzi +1)
答案 1 :(得分:4)
不,您不能将属性用作C#中的ref
或out
参数,因为CLR不支持此功能。传递实例变量应该可以正常工作。
作为旁注,VB.NET允许传递属性并使用一种名为“copy back ByRef”的技术,如this MSDN blog entry中所述。
答案 2 :(得分:4)
你不能用C#做到这一点 你可以使用VB.Net,但我认为这是个坏主意。下面的代码和输出显示它是如何做到的,并显示为什么我认为这是一个坏主意,我希望VB.net也不允许这样做
Public Class MySimpleClass
Private _privateInt As Integer
Public PublicInt As Integer
Public Property PrivateInt() As Integer
Get
Return _privateInt
End Get
Set(ByVal value As Integer)
_privateInt = value
End Set
End Property
Public Sub MyNotifier()
Console.WriteLine("PublicInt {0} : PrivateInt {1} : Values are not the same", PublicInt, PrivateInt)
End Sub
End Class
现在从子主程序中调用它,如此
Sub Main()
Dim sampleClass As New MySimpleClass
IterateAndUpdate(sampleClass.PrivateInt, sampleClass.PublicInt, AddressOf sampleClass.MyNotifier)
Console.WriteLine("Private {0} : Public {0} : values are the same ", sampleClass.PrivateInt, sampleClass.PublicInt)
Console.ReadKey()
End Sub
Sub IterateAndUpdate(ByRef anInt As Integer, ByRef anOtherInt As Integer, ByVal notifier As Action)
For i As Integer = 1 To 9
anInt = i
anOtherInt = i
notifier()
Next
End Sub
此输出
PublicInt 1:PrivateInt 0:值不一样
PublicInt 2:PrivateInt 0:值不一样
PublicInt 3:PrivateInt 0:值不一样
PublicInt 4:PrivateInt 0:值不一样
PublicInt 5:PrivateInt 0:值不一样
PublicInt 6:PrivateInt 0:值不一样
PublicInt 7:PrivateInt 0:值不一样
PublicInt 8:PrivateInt 0:值不一样
PublicInt 9:PrivateInt 0:值不一样
私人9:公众9:价值观相同
您可以看到PublicInt
成员在传递ByRef
时立即在sampleClass上更新,将PrivateInt
公开为属性仅在IterateAndUpdate
方法结束后更新。
因此,您会从完全相同的调用约定中获得明显不同的行为,这取决于您实现传递的项目的方式(看起来对IterateAndUpdate
的调用并不明显。
隐藏错误的可能性,或者微小的变化改变了预期的行为,这足以让我希望这个“功能”不存在。
在我看来,这不正常,因此它应该是
a)固定,这将为编译器团队付出相当大的努力,并可能引入重大变化
或
b)根本不工作
答案 3 :(得分:3)
传递给out参数的参数不能是属性。如果您尝试编译代码,则会出现编译错误。
属性,索引器或动态成员访问权限不能作为out或ref参数传递
原因是属性实际上不是字段(它可能有一个支持字段,但可能没有)。这是两种称为get_Foo
和set_Foo
的方法。有关为什么不起作用的详细说明,请参阅c# property and ref parameter, why no sugar?。
给出编译错误的示例代码:
class Program
{
public int Foo { get; set; }
public void Bar(out int x)
{
x = 5;
}
void Run()
{
Bar(out Foo); // compile error
}
static void Main()
{
new Program().Run();
}
}
答案 4 :(得分:0)
您可以将out
参数与字段(或已经说明的本地人)一起使用。