2013-05-09 4 views
1

Я получил классный метод here, чтобы проверить, получен ли тип от другого. Пока я был рефакторинг кода, я получил этот кусок GetBlah.Понимание этой функции, которая возвращает объект типа

public static bool IsOf(this Type child, Type parent) 
{ 
    var currentChild = child.GetBlah(parent); 

    while (currentChild != typeof(object)) 
    { 
     if (parent == currentChild) 
      return true; 

     if(currentChild.GetInterfaces().Any(i => i.GetBlah(parent) == parent)) 
      return true; 

     if (currentChild.BaseType == null) 
      return false; 

     currentChild = currentChild.BaseType.GetBlah(parent); 
    } 

    return false; 
} 

static Type GetBlah(this Type child, Type parent) 
{ 
    return child.IsGenericType && parent.IsGenericTypeDefinition 
     ? child.GetGenericTypeDefinition() 
     : child; 
} 

У меня возникли проблемы с пониманием того, что делает GetBlah и, следовательно, не может дать ему имя. Я имею в виду, что могу понять тернарное выражение как таковое и функцию GetGenericTypeDefinition, но я, похоже, не получаю его использования в методе IsOf, особенно аргумент parent, который передается. Может ли кто-нибудь выяснить, что на самом деле возвращает метод GetBlah?

Bonus: Предложите мне меткое имя метода :)

+1

Похоже, если оба родителя ребенка и дженерики, но разных типов ('' Список против '' Список для пример) метод предназначен для создания одного и того же родового типа ('List <>'), чтобы их можно было сравнить более корректно. – Patashu

+0

и какая теперь разница с методом 'Type.IsAssignableFrom' ?! – user287107

+0

Я уже ответил на ваш вопрос о методе GetBlah, но что вы пытаетесь сделать? Существует уже метод 'Type.IsAssignableFrom'. Вы также хотите знать, выводится ли 'List ' из 'List <>'? Если вам нужна помощь в этом, отправьте второй вопрос (и дайте мне комментарий с новой ссылкой!) :) –

ответ

3

Универсальные типы, как List<int> или List<string>. Все они используют однотипное определение типа: List<>.

IsGenericType вернет true это тип общего типа. Если тип является типичным определением типа, то IsGenericTypeDefinition должен возвращать значение true. Функция GetGenericTypeDefinition вернет определение типового типа общего типа.

Так что, если вы могли бы сделать:

typeof(List<int>).GetGenericTypeDefinition(); 

Вы получите typeof(List<>).

До сих пор теория!

Если вы проанализируете свой код правильно, оно вернет значение true для child происходит от parent. Так что я сделал небольшой перечень которых сочетание типа должен возвращать true (на мой взгляд):

A: int, IComparable<int> 
B: int, ValueType 
C: int, object 
D: List<int>, IList<int> 
E: List<int>, IEnumerable<int> 
F: List<int>, object 

G: List<int>, List<> 
H: List<int>, IList<> 
I: List<>, IList<> 
J: List<>, object 

Данный код не в одной точке: Каждый раз, когда parent имеет тип object, возвращается ложь. Это легко решается путем изменения While-условие в:

while (currentChild != null) 

Теперь к вашему Blah -функции. Что такое проверка, является ли родительское определение общего типа. Никакой класс «нормальный» (общий или нет) может быть получен из определения общего типа. Только определение общего типа может быть получено из другого определения общего типа. Поэтому, чтобы позволить случаю G и H стать истинным, необходимо сделать специальное преобразование. Если родительский тип является определением общего типа И когда ребенок может быть преобразован в определение общего типа, тогда ребенок будет преобразован в определение своего общего типа.

Это все, что он делает.

Так идеальное имя для вас функция может быть: ConvertChildToGenericTypeDefinitionIfParentIsAGenericTypeDefinitionAndTheChildIsAGenericType(...)

:)

+0

Мартин, я не думаю, что вы ответили на мой вопрос. Я знаю, что это значит. То, что я не понимаю, - это их значимость в коде. Другими словами, какую цель они выполняют, используя метод GetBlah. Думаю, @Patashu положил его в комментарии. Чтобы получить 'GetPossibleGenericTypeDefinition', все, что мне нужно сделать, это' child.IsGenericTypeDefinition? child.GetGenericTypeDefinition(): child', но в этом методе есть аргумент «parent», и он что-то там делает. Я не понимаю значимости этого аргумента, о чем я и говорю. – nawfal

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