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

获取在byref参数vb.net中传递的对象的名称,vb.net,reflection,Vb.net,Reflection,如何获取byref传递给方法的对象的名称 例如: 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,我应该可以

如何获取byref传递给方法的对象的名称

例如:

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:

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

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”。

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


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

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


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

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

示例:(使用LinqPad执行)


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

示例:(使用LinqPad执行)


很抱歉,这是你的解决方案。我在方法签名中留下了
(ByVal o作为对象)
,以防您对其进行更多操作

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

很抱歉,这是你的解决方案。我在方法签名中留下了
(ByVal o作为对象)
,以防您对其进行更多操作

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

如果您的程序相对于生成它的代码仍然位于同一位置,则这可能会起作用:

'  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, "\).*$", "")

您可以使用depth参数控制它在堆栈跟踪中挖掘的深度。4适合我的需要。您可能需要使用12或3。

如果您的程序相对于生成它的代码仍然处于相同的位置,这可能会起作用:

'  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, "\).*$", "")

您可以使用depth参数控制它在堆栈跟踪中挖掘的深度。4适合我的需要。您可能需要使用12或3。这显然是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

这显然是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

我想他是在询问变量名,而不是使用的类的名称,但作为替代解决方案,您可以查看该类型是否提供了可用于登录的信息。Ie DateTime进来了,然后一个Int32进来了等等。谢谢你,这很有帮助,但我真的在寻找变量名。我想他是在问变量名,而不是所使用的类的名称,但作为一种替代解决方案,你可以看到该类型是否提供了可用于登录的信息。Ie DateTime输入,然后Int32输入等等。谢谢,这很有帮助,但我确实在寻找变量名。@Hans Passant:“myobject”?不,不是。这是一个变量。用于日志记录。这是一个在没有GUI的情况下运行的过程,我尽量不重复代码。如果我能得到变量名的话,它会很适合日志。我现在必须把它作为字符串文本传递给我的方法。但“不”也是一个答案。谢谢有关打印“o”(我编辑了它)的代码示例,请参见我的问题。这可以在PHP中完成吗?也许那就是我记得拥有那种力量的地方哈哈。@John:据我所知,不是。。。您可以使用语法
$$varname
逐个变量名使用变量,但我不知道有哪种编程语言会保留变量名,甚至脚本语言也不会。您仍然可以通过使用更具描述性的名称来避免重复自己,例如
log.WriteLine(String.Format(“找到{0}个非用户打开的会话”,numSessions))
@Hans Passant:“myobject”?不,不是。这是一个变量。用于日志记录。这是一个在没有GUI的情况下运行的过程,我尽量不重复代码。如果我能得到变量名的话,它会很适合日志。我现在必须把它作为字符串文本传递给我的方法。但“不”也是一个答案。谢谢有关打印“o”(我编辑了它)的代码示例,请参见我的问题。这可以在PHP中完成吗?也许那就是我记得拥有那种力量的地方哈哈。@John:据我所知,不是。。。您可以使用语法
$$varname
逐个变量名使用变量,但我不知道有哪种编程语言会保留变量名,甚至脚本语言也不会。您仍然可以通过使用更具描述性的名称来避免重复,例如
log.WriteLine(String.Format(“Found{0}非用户打开的会话”,numSessions))