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

本文关键字:NET 参数 Ref VB 中的 通过 | 更新日期: 2023-09-27 18:16:09

我有有关传递参数byRef的问题,我有VB。基于。NET的类库,其中一些函数用byref参数类型定义。这些参数是父类对象,当我试图调用这个函数并在byref参数中传递子类对象时,它在VB中工作。. NET,但我无法在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

VB中的实现类

Public Class Parent
        Public Function Show(ByRef value As Father) As Boolean
            Dim test As String = value.Cast
            Return True
        End Function

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

Public Function Show2() As Boolean
            Dim s As New Son
            Dim result As Boolean = Show(s)
            Return True
        End Function
    End Class

//但是当我在c#中做同样的事情时

Parent p = new Parent();
            Son s = new Son();
            Father f = new Father();
            p.Show(ref s);

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

Thanks in advance

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

c#对此是严格的,通过引用传递的变量必须与方法参数类型完全匹配。VB。NET对此是宽容的,它的编译器重写您的代码并创建所需类型的变量。大致如下,用c#表示:

    Son s = new Son();
    Father $temp = (Father)s;
    p.Show(ref $temp);
    s = (Son)$temp;

这很好,但不是没有问题。失败模式是Show()方法将new对象分配给错误类型的参数。因为参数类型是Father,所以允许创建Father对象。然而,这将使上面片段中的第4条语句失败,不能将父转换为子。这不是很好,异常将在错误的语句中引发,真正的问题位于Show()方法中。你可以对此挠头一段时间,至少因为在VB中实际上是不可见的。. NET源代码。哎哟。c#强制您显式地编写上面的代码片段,这解决了您的问题。

此时,您应该惊呼:"等等,Show()方法实际上并没有创建一个新对象!"这是很好的洞察力,您将发现这段代码中的真正问题,Show()方法应该而不是声明参数ByRef。只有当方法重新分配参数并且需要将更改传播回调用方时,才应该使用它。最好完全避免,方法应该根据对象的返回值返回对象。VB中的函数。. NET代替Sub.

ByRef允许函数修改托管指针并使其指向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.

然而,如果你的方法Show真的不修改托管指针,那么就没有理由采用ByRef:只需传递ByVal,你仍然可以修改对象本身。