通用基本类型的全名

时间:2013-11-25 17:38:24

标签: c# generics reflection

我有一个类的层次结构,我试图从中获取类型名称:

class Alice
    :ThirdPersonCharacter<Foo, Bar>

class ThirdPersonCharacter<A, B>
    :BaseHumanoidCharacter<A, B>, ISomeInterface
    where A : Something

class BaseHumanoidCharacter<A, B>
    : Entity,
    ISomeOtherInterface
    where A : Something

我想得到Alice的所有基类型,所以我这样做:

private static IEnumerable<Type> BaseTypes(Type t)
{
    while (t.BaseType != null)
    {
        yield return t.BaseType;
        t = t.BaseType;
    }
}

var aliceTypes = baseTypes(typeof(Alice)).Select(a => a.AssemblyQualifiedName).ToArray();

问题是找到BaseHumanoidCharacter的类型是:

{Name = "BaseHumanoidCharacter`2" FullName = null}

当然我真正想要的是:

{Name = "BaseHumanoidCharacter`2[[X.Y.Z.Foo, AssemblyName, version=123, Culture=whatever, PublicKey=stuff],[X.Y.Z.Bar, AssemblyName, version=123, Culture=whatever, PublicKey=stuff]]", FullName = "Something that isn't null"}

有没有办法修改这个系统,为我提供填充了通用参数的有用类型,并且它们的FullName不为空?

1 个答案:

答案 0 :(得分:0)

FullName会返回与您正在寻找的内容非常相似的内容:

typeof(Tuple<int, string>).FullName
// System.Tuple`2[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

这与您的示例之间存在一些差异,根据您打算如何使用它可能会或可能不会重要

  1. 它包含第一个类型的命名空间。您可以通过根据Namespace
  2. 的长度获取子字符串来解决此问题
  3. 它不仅包括程序集名称,还包括完整程序集标识字符串(Version,Culture,PublicKeyToken),使其非常长。
  4. 格式有点不同,类型周围还有一对额外的[]括号。
  5. 如果最后两个问题存在,您应该能够使用TypeGenericTypeArgumentsNameFullName等各种属性自行构建字符串。 )和Assembly,并在需要时与Splitting结合使用(例如,将程序集名称与其他信息分开)。

    以下是选择NameFullName

    的示例
    var aliceTypes = BaseTypes(typeof(Alice)).Where(x => x == 
                               typeof(BaseHumanoidCharacter<Foo, Bar>))
                                 .Select(a => new { a.Name, a.FullName }).ToArray();
    Console.WriteLine(aliceTypes.Single());