问题
I have question related passing parameters byRef, I have VB.NET based class library in which some functions are defined with byref argument types. These parameters are parent class objects and when I tried to call this function and pass child class object in byref argument it works in VB.NET but I am unable to do same thing in C#
following is test code i am trying
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
Implementation class in VB
Public Class Parent
Public Function Show(ByRef value As Father) As Boolean
Dim test As String = value.Cast
Return True
End Function
// Herer I can call Show method and pass child object to ByRef type argument and it works
Public Function Show2() As Boolean
Dim s As New Son
Dim result As Boolean = Show(s)
Return True
End Function
End Class
// But when i try same thing in c#
Parent p = new Parent();
Son s = new Son();
Father f = new Father();
p.Show(ref s);
I get error that Son cannot convert to father , I already test it works in VB but how can I make it work in c#? as I have class library in dll format
Thanks in advance
回答1:
C# is strict about this, a variable that's passed by reference must be an exact match with the method argument type. VB.NET is forgiving about that, its compiler rewrites your code and creates a variable of the required type. Roughly like this, expressed in C#:
Son s = new Son();
Father $temp = (Father)s;
p.Show(ref $temp);
s = (Son)$temp;
Which is nice, but not without problems. The failure mode is when the Show() method assigns a new object to its argument of the wrong type. It is allowed to create a Father object since the argument type is Father. That however will make the 4th statement in the above snippet fail, can't cast Father to Son. That's not so pretty, the exception will be raised at the wrong statement, the true problem is located in the Show() method. You can scratch your head over that for a while, not in the least because the cast is not actually visible in your VB.NET source code. Ouch. C# forces you to write the above snippet explicitly, which solves your problem.
At this point you should exclaim "But wait, the Show() method doesn't actually create a new object!" That's good insight and you'll have found the true problem in this code, the Show() method should not declare the argument ByRef. It should only be used when a method reassigns the argument and that change needs to be propagated back to the caller. Best avoided entirely, an object should be returned by a method by its return value. Function in VB.NET instead of Sub.
回答2:
ByRef
allows the function to modify the managed pointer and make it point to something other than a Son
, therefore C# won't allow you to pass a managed pointer to Son
directly. However, you can do this:
Son s = new Son();
Father f = s;
p.Show(ref f);
s = (Son)f; //Success if f still points to a Son, InvalidCastException otherwise.
However, if your method Show
really does not modify the managed pointer, then there is no reason for taking it ByRef
: Just pass it ByVal
and you'll still be able to modify the object itself.
来源:https://stackoverflow.com/questions/16854616/by-ref-parameters-in-vb-net-and-c-sharp