0

Im trying to get the name of a variable in runtime using reflection, i read a lot and find in other question a code in c# for that, now in vb.net the code looks like this

Public Shared Function GetParameterName(Of T As Class)(item As T) As String
    If item Is Nothing Then
        Return String.Empty
    End If

    Return GetType(T).GetProperties()(0).Name
End Function

the problems is when i try to call the function in c# i would be like this where test is the variable

GetParameterName(new {test});

but in Visual im cant call like that and if try like this

GetParameterName({test})

or

GetParameterName(New Object() {test})

the generic method doesn't recognize the variable the properties like name just say "Length" and the value "1"

maybe is a simple thing but i really appreciate your help

Regards

Update, Here is the original C# code that works no matter type

public static string GetParameterName<T>(T item) where T : class
    {
        if (item == null)
            return string.Empty;

        return typeof(T).GetProperties()[0].Name;
    }

Update 3

yes i also dint notice the anonymous type, for other person who have a similar scenario here is te function to get the name and information of a variable

 Public Shared Function GetWatch(Of T1)(item1 As T1) As String
    Dim info As String = ""
    Try
        If GetType(T1).GetProperties()(0).GetValue(item1, Nothing) Is Nothing And GetType(T1).GetProperties()(0).Name <> "Not" Then
            info &= "--------"
            info &= vbCrLf
            info &= "Nombre de la variable: " & GetType(T1).GetProperties()(0).Name
            info &= vbCrLf
            info &= "Tipo de la variable: " & GetType(T1).GetProperties()(0).PropertyType.Name
            info &= vbCrLf
            info &= "Valor de la variable: Nothing"
            info &= vbCrLf
        Else
            If GetType(T1).GetProperties()(0).GetValue(item1, Nothing).ToString = "Not" Then
                info &= ""
            Else
                    info &= vbCrLf
                    info &= "--------"
                    info &= vbCrLf
                    info &= "Nombre de la variable: " & GetType(T1).GetProperties()(0).Name
                    info &= vbCrLf
                    info &= "Tipo de la variable: " & GetType(T1).GetProperties()(0).PropertyType.Name
                    info &= vbCrLf
                    info &= "Valor de la variable: " & GetType(T1).GetProperties()(0).GetValue(item1, Nothing).ToString
                    info &= vbCrLf
                    info &= "--------"
                    info &= vbCrLf

              End If

        End If
Return info

Catch e As Exception
            Return ""

        End Try

    End Function

Thanks a lot to everybody for the help!!

V-mos
  • 39
  • 6

1 Answers1

1

I don't really know how I missed it, but you clearly say in your question that you want to get the name of a variable. The C# code is using a so-called anonymous type, which is instantiated with only one property.

The VB.NET equivalent is:

GetParameterName(New With {test})

Read more: Anonymous Types (Visual Basic) - MSDN.


-- Old answer, kept in case someone wants to use this for another purpose --

You're creating an array of whatever test is, thus GetType(T) will return yourNamespace.yourType[] (or in your third case: System.Object[]). What you're getting is the array's Length property, which has the value 1 since it indicates how many items there is in the {test} array.

If you want to get a property from the underlying type you should first check if the object inherits IEnumerable (which arrays, lists and collections do), and if it does then call the GetElementType() method to get the actual underlying type.

This works for me:

Public Shared Function GetParameterName(Of T As Class)(item As T) As String
    If item Is Nothing Then
        Return String.Empty
    End If

    If GetType(IEnumerable).IsAssignableFrom(GetType(T)) Then 'This is an array, collection or a list, etc.
        Dim ElementType As Type = GetType(T).GetElementType()
        If ElementType IsNot Nothing Then 'Does this have an underlying type?
            Return ElementType.GetProperties()(0).Name
        End If
    End If

    Return GetType(T).GetProperties()(0).Name 'This is not a list type, or it's a list type that doesn't have an underlying type (ex. ArrayList).
End Function
Visual Vincent
  • 18,045
  • 5
  • 28
  • 75
  • Ok Thats make senses how ever wath i try to achieve is get the name of the variable in this case test is a integer so in c# im able to get the name using the same function but in visual im not sure how, if i call like GetParameterName(test) and test is a string returns "chars" and if test is a integer trowhs an error saying That cant infer a integer with the class construimos – V-mos Apr 21 '17 at 00:29
  • @V-mos : First of all an `Integer` doesn't have any properties so this code won't work for them (as you see there's no property list on the [**MSDN Documentation**](https://msdn.microsoft.com/en-us/library/system.int32.aspx)). Secondly, `(Of T As Class)` forces `T` to be a class, whilst an integer is a `Structure`. Change it to `(Of T)` to allow all types. – Visual Vincent Apr 21 '17 at 00:47
  • @V-mos : Pretty much none of the standard primitive types have got any properties, so this code will fail for all of them: `(U)Integer, (U)Long, (U)Short, (S)Byte, Double, Single, Decimal, Char, Boolean`. -- There's a [**difference between a property and a field**](http://stackoverflow.com/questions/295104/what-is-the-difference-between-a-field-and-a-property-in-c). – Visual Vincent Apr 21 '17 at 00:51
  • im aware of that is just that i dont know how in c# the code works with integer or string or long, but in VB im just no able to do same, if change to `(Of T)` just show "Chars" for a string and for the rest i got an exception in the question i left the original c# code – V-mos Apr 21 '17 at 16:44
  • @V-mos : When I run `GetParameterName(new {test});` it returns `test` because `new {test}` creates an anonymous type with **one** property called `test`. Read more about [**anonymous types**](https://msdn.microsoft.com/en-us/library/bb397696.aspx). -- I actually haven't though of that before, but I now realize that's the behaviour you want... Can't see how I missed that since you wrote so in the question ;). I'll update my answer. – Visual Vincent Apr 21 '17 at 17:26