我有问题相关的传递参数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
// 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
//但是当我在c#中尝试相同的事情时
Parent p = new Parent();
Son s = new Son();
Father f = new Father();
p.Show(ref s);
我得到Son无法转换为父亲的错误,我已经测试它在VB中工作但我怎样才能使它在c#中工作?因为我有dll格式的类库
提前致谢
答案 0 :(得分:10)
C#对此严格,通过引用传递的变量必须与方法参数类型完全匹配。 VB.NET对此感到宽容,它的编译器重写你的代码并创建一个所需类型的变量。粗略地喜欢这个,用C#表示:
Son s = new Son();
Father $temp = (Father)s;
p.Show(ref $temp);
s = (Son)$temp;
哪个好,但不是没有问题。失败模式是Show()方法将 new 对象分配给错误类型的参数。由于参数类型是父,因此允许创建父对象。然而,这将使上述片段中的第4个陈述失败,无法将父亲施放给儿子。那不太好,异常将在错误的语句中引发,真正的问题在于Show()方法。你可以暂时解决这个问题,但至少是因为你的VB.NET源代码中实际上看不到强制转换。哎哟。 C#强制您明确编写上述代码段,以解决您的问题。
此时你应该感叹"但是等等,Show()方法实际上并没有创建一个新对象!"这个很好的见解并且你已经在这段代码中找到了真正的问题,Show()方法应该不声明参数ByRef。它只应在方法重新分配参数并且需要将更改传播回调用方时使用。最好完全避免,一个对象应该由一个方法返回它的返回值。 VB.NET中的函数而不是Sub。
答案 1 :(得分:4)
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
,您仍然可以修改对象本身。