获取泛型类型的源代码表示?

时间:2016-09-30 21:02:14

标签: c# generics

我试图在字符串中获取泛型类型我得到更像IL表示的东西,我需要真正的源代表来发送它。

Type t = typeof(Stack<string>);

string source = t.Name;        //Stack`1[System.String]
string source = t.ToString();  //System.Collections.Generic.Stack`1[System.String]

我只需要:

string source //Stack<string>

2 个答案:

答案 0 :(得分:3)

我有这种扩展方法GetPrettyName()。基本上就是这样:

public static string GetPrettyName(this Type type)
{
    var retval = type.Name;

    if (type.IsGenericType)
    {
        var genargNames = type.GetGenericArguments().Select(t => GetPrettyName(t));
        var idx = type.Name.IndexOf('`');
        var typename = (idx > 0) ? type.Name.Substring(0, idx) : type.Name;
        retval = String.Format("{0}.{1}<{2}>", type.Namespace, typename, String.Join(", ", genargNames));
    }
    else if (type.IsArray)
    {
        retval = GetPrettyName(type.GetElementType()) + "[]";
    }
    else if (String.IsNullOrEmpty(retval))
    {
        retval = type.Name;
    }

    return retval;
}

它以递归方式对每个泛型类型参数进行操作,并以“ close 到代码表示的格式构建全名。它足以满足我们的目的(它仅用于记录消息)。它可以处理泛型和数组,但不能很好地处理实体框架代理。

答案 1 :(得分:0)

这是Amy回答的一个版本,支持嵌套类和多维数组。

public static string GetSourceCodeRepresentation(this Type type)
{
    return GetSourceCodeRepresentationInt(type, new List<Type>());
}

private static string GetSourceCodeRepresentationInt(Type type, List<Type> travesed)
{
    travesed.Add(type);

    var prefixName = string.Empty;
    if (type.DeclaringType != null)
    {
        if (!travesed.Contains(type.DeclaringType))
            prefixName = GetSourceCodeRepresentationInt(type.DeclaringType, travesed) + ".";
    }
    else if (!string.IsNullOrEmpty(type.Namespace))
        prefixName = type.Namespace + ".";

    if (type.IsGenericType)
    {
        var genargNames = type.GetGenericArguments().Select(type1 => GetSourceCodeRepresentationInt(type1, new List<Type>()));
        var idx = type.Name.IndexOf('`');
        var typename = idx > 0 ? type.Name.Substring(0, idx) : type.Name;
        return $"{prefixName}{typename}<{string.Join(", ", genargNames.ToArray())}>";
    }

    if (type.IsArray)
    {
        return $"{GetSourceCodeRepresentation(type.GetElementType())}[{new string(Enumerable.Repeat(',', type.GetArrayRank() - 1).ToArray())}]";
    }

    return $"{prefixName}{type.Name}";
}