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

我有问题相关的传递参数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格式的类库

提前致谢

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

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

哪个好,但不是没有问题。 失败模式是Show()方法将对象分配给其错误类型的参数。 由于参数类型是父,因此允许创建父对象。 然而,这将使上述片段中的第4个陈述失败,无法将父亲施放给儿子。 这不是那么漂亮,exception将在错误的语句中引发,真正的问题位于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 ,您仍然可以修改对象本身。