代码之家  ›  专栏  ›  技术社区  ›  CJ7

C:函数中的“out”参数可以是对象属性/变量吗?[复制品]

  •  9
  • CJ7  · 技术社区  · 14 年前

    这个问题已经有了答案:

    C:函数中的“out”参数可以是对象属性/变量吗?

    如:

    我可以调用如下函数:

    someFunction(x, y, out myObject.MyProperty1)
    
    5 回复  |  直到 14 年前
        1
  •  6
  •   Ruben Bartelink    14 年前

    属性是[一对get-and-set]方法,具有调用它们的可爱语法,使它们看起来像字段。

    out参数可以是对字段或基于堆栈的“字段”(即局部变量)的引用。

    这种差距的桥接通常不由语言来解决(而且绝对不直接由clr和il模型来解决)。(+1 on@heinzi用于vb欺骗参考)

        2
  •  4
  •   Heinzi    14 年前

    不,您不能使用 财产 作为一个 ref out C中的参数,因为clr不支持此参数。路过 实例变量 应该工作得很好。

    作为旁注,vb.net允许传递 性质 并使用一种称为“复制回byref”的技术,如中所述。 this MSDN blog entry .

        3
  •  4
  •   Ruben Bartelink    14 年前

    你不能用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:值不相同
    private 9:public 9:值相同

    你可以看到 PublicInt 通过时的成员 ByRef 在sampleClass上立即更新,将 PrivateInt 仅在 IterateAndUpdate 方法结束。

    因此,您从完全相同的调用约定中获得明显不同的行为,这取决于您如何实现传递的项(从调用到 迭代重复日期 .
    隐藏bug或进行小改动的潜力足以改变预期的行为,我希望这个“特性”不存在。

    在我看来,这是不正确的,因此它应该是
    a)已修复,这对编译器团队来说需要付出相当大的努力,并可能引入破坏性的更改。

    b)根本不工作

        4
  •  3
  •   Community Vlad V    7 年前

    传递给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();
        }
    }
    
        5
  •  0
  •   leppie    14 年前

    你可以使用 out 带字段的参数(或前面提到的局部变量)。