By Ref parameters in VB.NET and C#

ぐ巨炮叔叔 提交于 2019-12-07 02:05:52

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!