Получить имя объекта, переданного в параметре byref vb.net - PullRequest
0 голосов
/ 30 августа 2011

Как я могу получить имя объекта, который был передан 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

Я использую это для регистрации. Я использую один метод несколько раз, и было бы неплохо записать имя переменной, которую я передал ему. Поскольку я передаю его по ссылке, я должен быть в состоянии получить это имя, верно?

Для тех, кто предоставил ответ:

Это даст вам имя параметра в методе и его типе, но не имя переменной, которая была передана по ссылке.

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 ]

3 голосов
/ 30 августа 2011

Это невозможно.Имена переменных не хранятся в IL, только имена членов класса или классов пространства имен.Передача по ссылке не имеет абсолютно никакой разницы.Вы даже не сможете заставить его напечатать «о».

Кроме того, зачем вам это вообще нужно?

1 голос
/ 30 августа 2011

В качестве альтернативы вы можете получить «Тип» объекта, используя отражение.

Пример: (используйте 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
0 голосов
/ 03 октября 2018

Очевидно, именно так средства управления Visual Basic решают проблему.

У них есть базовый класс элементов управления, который в дополнение к любым другим общим свойствам, которые могут иметь эти элементы управления, имеет свойство name.

Например: Public MustInherit Class NamedBase Публичное имя As String End Class

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

0 голосов
/ 02 февраля 2013

Если ваша программа все еще находится в том же месте относительно кода, который ее создал, это может сработать:

'  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.

0 голосов
/ 31 августа 2011

Извините, но это ваше решение. Я оставил (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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...