使用类约束调用泛型方法

时间:2017-04-20 23:03:59

标签: .net vb.net generics reflection

我试图在运行时使用反射来获取变量的名称,我阅读了很多并在其他问题中找到了c#中的代码,现在在vb.net中代码看起来像这样

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

问题是当我尝试在c#中调用函数时,i会像这样,其中test是变量

GetParameterName(new {test});

但在视觉上无法调用,如果尝试这样

GetParameterName({test})

GetParameterName(New Object() {test})

通用方法没有识别变量,如名称这样的属性只是说"长度"和价值" 1"

也许是一件简单的事情,但我非常感谢你的帮助

此致

更新,以下是无论类型

的原始C#代码
public static string GetParameterName<T>(T item) where T : class
    {
        if (item == null)
            return string.Empty;

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

更新3

是的我也注意到匿名类型,对于其他有类似情况的人来说,这里有te函数来获取变量的名称和信息

 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

非常感谢大家的帮助!!

1 个答案:

答案 0 :(得分:1)

我真的不知道我是如何错过它的,但你在问题中清楚地表明你想得到变量的名称。 C#代码使用的是所谓的anonymous type,它只用一个属性进行实例化。

VB.NET等价物是:

GetParameterName(New With {test})

了解详情:Anonymous Types (Visual Basic) - MSDN

- 旧答案,以防万一有人想将其用于其他目的 -

您正在创建任何test 数组 ,因此GetType(T)将返回yourNamespace.yourType[](或你的第三种情况:System.Object[])。你得到的是阵列Length property,其值1,因为它表示{test}数组中有多少项。

如果要从基础类型获取属性,首先应检查对象是否继承IEnumerable(哪些数组,列表和集合执行),如果是,则调用GetElementType() method得到实际的基础类型。

这对我有用:

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