2013-11-25 3 views
0

У меня есть иерархия классов, которые я пытаюсь получить имена Типа из:ПолноеИмя родового базовый типа

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 

Я хочу, чтобы все базовые типов Алисы, так что я это делаю :

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"} 

Есть ли способ, чтобы изменить эту систему, чтобы дать мне полезные типы с их родовыми параметрами заполненных, и их ПолноеИмя не равно нулю?

+0

Для того, чтобы полностью понять иерархию классов, было бы полезно, если вы также показать класс символов, что Алиса является производным от - или это опечатка ? – Markus

+0

Было да, извините. Я имел в виду более специфический ThirdPersonCharacter. – Martin

ответ

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. Он включает в себя не только имя сборки, но и полную идентификационную строку сборки (Version, Culture, PublicKeyToken), что делает ее довольно длинной.
  3. Формат немного отличается, есть дополнительные пары скобок [] вокруг типов.

Если эти последние два являются проблематичными, вы должны быть в состоянии построить строку самостоятельно, используя различные свойства Type (GenericTypeArguments, Name, FullName и т.д.) и Assembly, в сочетании с Splitting, где это необходимо (например, для разделения название сборки из другой информации).

Вот пример выбора Name и FullName:

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

Ой, разницы в формате просто ошибка с моей стороны. Я исправлю это в вопросе. Реальная проблема: FullName is * not * возвращает такую ​​строку (что и следовало ожидать), по какой-то причине в этом случае она возвращает null. Я ожидаю, что это что-то конкретное о том, как настраивается вся система, почему именно я привел пример всей иерархии классов. – Martin

+0

В частности, я подозреваю, что использование BaseType - неправильная вещь, но я не уверен, какую альтернативу использовать. – Martin

+0

@Martin 'BaseType' в порядке. Я не могу воспроизвести вашу проблему с указанием «null». См. Вывод http://ideone.com/K60q3Z –

Смежные вопросы