通过VB.NET和C#中的Ref参数

use*_*901 6 c# vb.net pass-by-reference byref

我有问题相关的传递参数byRef,我有基于VB.NET的类库,其中一些函数使用byref参数类型定义.这些参数是父类的对象,当我试图调用此函数,并传递子类对象的工作在VB.NET ByRef参数,但我不能做同样的事情在C#

以下是我正在尝试的测试代码

Public Class Father

        Private _Cast As String
        Public Property Cast() As String
            Get
                Return _Cast
            End Get
            Set(ByVal value As String)
                _Cast = value
            End Set
        End Property

    End Class


 Public Class Son
        Inherits Father

        Private _MyName As String
        Public Property Myname() As String
            Get
                Return _MyName
            End Get
            Set(ByVal value As String)
                _MyName = value
            End Set
        End Property


    End Class
Run Code Online (Sandbox Code Playgroud)

VB中的实现类

Public Class Parent

        Public Function Show(ByRef value As Father) As Boolean
            Dim test As String = value.Cast
            Return True
        End Function
Run Code Online (Sandbox Code Playgroud)

// Herer我可以调用Show方法并将子对象传递给ByRef类型参数,它可以工作

Public Function Show2() As Boolean

            Dim s As New Son
            Dim result As Boolean = Show(s)

            Return True
        End Function

    End Class
Run Code Online (Sandbox Code Playgroud)

//但是当我在c#中尝试相同的事情

Parent p = new Parent();
            Son s = new Son();
            Father f = new Father();

            p.Show(ref s);
Run Code Online (Sandbox Code Playgroud)

我得到Son无法转换为父亲的错误,我已经测试它在VB中工作但我怎样才能使它在c#中工作?因为我有dll格式的类库

提前致谢

Han*_*ant 10

C#对此严格,通过引用传递的变量必须与方法参数类型完全匹配.VB.NET对此很宽容,它的编译器会重写你的代码并创建一个所需类型的变量.粗略地喜欢这个,用C#表示:

    Son s = new Son();
    Father $temp = (Father)s;
    p.Show(ref $temp);
    s = (Son)$temp;
Run Code Online (Sandbox Code Playgroud)

哪个好,但不是没有问题.失败模式是Show()方法将对象分配给其错误类型的参数.由于参数类型是父,因此允许创建父对象.然而,这将使上述片段中的第4个陈述失败,无法将父亲施放给儿子.这不是那么漂亮,异常将在错误的语句中引发,真正的问题位于Show()方法中.你可以暂时解决这个问题,但至少是因为你的VB.NET源代码中实际上看不到强制转换.哎哟.C#强制您明确编写上述代码段,以解决您的问题.

此时你应该惊叹"但等等,Show()方法实际上并没有创建一个新对象!" 这是很好的启示,你会发现这段代码的真正问题,Show()方法应该声明参数为ByRef.它只应在方法重新分配参数并且需要将更改传播回调用方时使用.最好完全避免,一个对象应该由一个方法返回它的返回值.VB.NET中的函数而不是Sub.


Med*_*noc 4

ByRef允许函数修改托管指针并使其指向 a 以外的其他内容Son,因此 C# 不允许您Son直接传递托管指针。但是,您可以这样做:

Son s = new Son();
Father f = s;
p.Show(ref f);
s = (Son)f; //Success if f still points to a Son, InvalidCastException  otherwise.
Run Code Online (Sandbox Code Playgroud)

但是,如果您的方法Show确实不修改托管指针,则没有理由采用它ByRef:只需传递它ByVal,您仍然可以修改对象本身。