获取在byref参数vb.net中传递的对象的名称

时间:2011-08-29 22:30:49

标签: vb.net reflection

如何获取通过ref传递给方法的对象的名称?

示例:

Dim myobject as object

sub mymethod(byref o as object)
    debug.print(o.[RealName!!!!])
end sub

sub main()
    mymethod(myobject)
    'outputs "myobject" NOT "o"
end sub

我正在使用它进行日志记录。我多次使用一个方法,记录传递给它的变量的名称会很好。因为我传递了byref,我应该能得到这个名字,对吧?

对于提供答案的minitech:

这将为您提供方法中的参数名称及其类型,但不提供由ref传递的变量的名称。

using system.reflection

Dim mb As MethodBase = MethodInfo.GetCurrentMethod()
For Each pi As ParameterInfo In mb.GetParameters()
    Debug.Print("Parameter: Type={0}, Name={1}", pi.ParameterType, pi.Name)
Next

如果你把它放在上面的“mymethod”中你会得到“o”和“Object”。

5 个答案:

答案 0 :(得分:3)

那是不可能的。变量名称不存储在IL中,只存储在类成员或命名空间类的名称中。通过引用传递它绝对是零差异。你甚至无法打印出“o”。

此外,你为什么要这样做?

答案 1 :(得分:1)

或者,您可以使用反射获取对象的“类型”。

示例:(使用LinqPad执行)

Sub Main    
  Dim myDate As DateTime =  DateTime.Now
  MyMethod(myDate)

  Dim something As New Something
  MyMethod(something)       
End Sub

Public Class Something
   Public Sub New
    Me.MyProperty = "Hello"
   End Sub
   Public Property MyProperty As String
End Class

Sub MyMethod(Byref o As Object)
   o.GetType().Name.Dump()
End Sub

答案 2 :(得分:0)

很抱歉,但这是您的解决方案。我在方法签名中留下(ByVal o As Object),以防你用它做更多的事情。

Sub MyMethod(ByVal o As Object, ByVal name As String)
    Debug.Print(name)
End Sub

Sub Main()
   MyMethod(MyObject, "MyObject")
End Sub

或者你可以创建一个界面,但这只允许你对你设计的类使用MyMethod。您可以采取更多措施来改进它,但正如此代码所示,您只能在创建时设置RealName

Interface INamedObject
    Public ReadOnly Property RealName As String
End Interface

Class MyClass
    Implements INamedObject

    Public Sub New(ByVal RealName As String)
        _RealName = RealName
    End Sub

    Private ReadOnly Property RealName As String Implements INamedObject.RealName
        Get
            Return _RealName
        End Get
    End Property
    Private _RealName As String
End Class

Module Main
    Sub MyMethod(ByVal o As INamedObject)
        Debug.Print(o.RealName)
    End Sub

    Sub Main()
        Dim MyObject As New MyClass("MyObject")
        MyMethod(MyObject)
    End Sub
End Module

答案 3 :(得分:0)

如果你的程序仍然在相对于制作它的代码的相同位置,这可能有效:

'  First get the Stack Trace, depth is how far up the calling tree you want to go
Dim stackTrace As String = Environment.StackTrace
Dim depth As Integer = 4

'  Next parse out the location of the code
Dim delim As Char() = {vbCr, vbLf}
Dim traceLine As String() = stackTrace.Split(delim, StringSplitOptions.RemoveEmptyEntries)
Dim filePath As String = Regex.Replace(traceLine(depth), "^[^)]+\) in ", "")
filePath = Regex.Replace(filePath, ":line [0-9]+$", "")
Dim lineNumber As String = Regex.Replace(traceLine(depth), "^.*:line ", "")

'  Now read the file
Dim program As String = __.GetStringFromFile(filePath, "")

'  Next parse out the line from the class file
Dim codeLine As String() = program.Split(delim)
Dim originLine As String = codeLine(lineNumber * 2 - 2)

'  Now get the name of the method doing the calling, it will be one level shallower
Dim methodLine As String = Regex.Replace(traceLine(depth - 1), "^   at ", "")
Dim methodName = Regex.Replace(methodLine, "\(.*\).*$", "")
methodName = Regex.Replace(methodName, "^.*\.", "")

'  And parse out the variables from the method
Dim variables As String = Regex.Replace(originLine, "^.*" & methodName & "\(", "")
variables = Regex.Replace(variables, "\).*$", "")

您可以使用深度参数控制深入到堆栈跟踪中的深度。 4适合我的需要。您可能需要使用1 2或3。

答案 4 :(得分:0)

这显然是Visual Basic控件处理问题的方式。

它们具有基本的控件类,除了这些控件的任何其他常用属性之外,这些控件还可能具有name属性。

例如:     公共MustInherit类NamedBase     公共名称为字符串     结束班

Public Class MyNamedType
    Inherits NamedBase
    public Value1 as string
    public Value2 as Integer
End Class

dim x as New MyNamedType

x.name = "x"
x.Value1 = "Hello, This variable is name 'x'."
x.Value2 = 75

MySubroutine(x)

public sub MySubroutine(y as MyNamedType)
    debug.print("My variable's name is: " & y.name)
end sub

中间窗口的输出应为:

我的变量的名称是:x