Проверьте, получен ли класс из универсального класса

287
задан Wai Ha Lee 2 October 2015 в 05:43
поделиться

7 ответов

Попробуйте этот код

static bool IsSubclassOfRawGeneric(Type generic, Type toCheck) {
    while (toCheck != null && toCheck != typeof(object)) {
        var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
        if (generic == cur) {
            return true;
        }
        toCheck = toCheck.BaseType;
    }
    return false;
}
408
ответ дан xanadont 23 November 2019 в 01:48
поделиться

Вот немного метода, который я создал для проверки, что объект получен из определенного типа. Работает отлично для меня!

internal static bool IsDerivativeOf(this Type t, Type typeToCompare)
{
    if (t == null) throw new NullReferenceException();
    if (t.BaseType == null) return false;

    if (t.BaseType == typeToCompare) return true;
    else return t.BaseType.IsDerivativeOf(typeToCompare);
}
9
ответ дан 23 November 2019 в 01:48
поделиться

Код JaredPar работает, но только на один уровень наследования. Для неограниченных уровней наследования используйте следующий код

public bool IsTypeDerivedFromGenericType(Type typeToCheck, Type genericType)
{
    if (typeToCheck == typeof(object))
    {
        return false;
    }
    else if (typeToCheck == null)
    {
        return false;
    }
    else if (typeToCheck.IsGenericType && typeToCheck.GetGenericTypeDefinition() == genericType)
    {
        return true;
    }
    else
    {
        return IsTypeDerivedFromGenericType(typeToCheck.BaseType, genericType);
    }
}
9
ответ дан user53564 23 November 2019 в 01:48
поделиться

(Повторно отправленный из-за крупной перезаписи)

ответ кода JaredPar является фантастическим, но у меня есть подсказка, которая сделала бы его ненужным, если Ваши универсальные типы не основаны на параметрах типа значения. Я был одержим тем, почему оператор, не работал бы, таким образом, я также зарегистрировал результаты своего экспериментирования для дальнейшего использования. Улучшите этот ответ для дальнейшего улучшения его ясности.

ПОДСКАЗКА:

, Если Вы удостоверяетесь, что Ваша реализация GenericClass наследовалась абстрактному неуниверсальному базовому классу, такому как GenericClassBase, Вы могли задать тот же вопрос без любой проблемы вообще как это:

typeof(Test).IsSubclassOf(typeof(GenericClassBase))
<час>

IsSubclassOf ()

Мое тестирование указывает, что IsSubclassOf () не работает над универсальными типами без параметров такой как [1 116]

typeof(GenericClass<>)

, тогда как это будет работать с [1 117]

typeof(GenericClass<SomeType>)

Поэтому, следующий код будет работать на любую деривацию GenericClass<>, принимая Вас готовы протестировать на основе SomeType:

typeof(Test).IsSubclassOf(typeof(GenericClass<SomeType>))

единственное время я могу предположить, что Вы хотели бы протестировать GenericClass<> находится в сменном сценарии платформы.

<час>

Мысли о "являются" оператором

Во время проектирования, которое C# не позволяет использованию дженериков без параметров, потому что они - по существу не полный тип CLR в той точке. Поэтому необходимо объявить, что универсальные переменные с параметрами, и именно поэтому "являются" оператором, так мощно для работы с объектами. Кстати, оператор, также не может оценить универсальные типы без параметров.

оператор, протестирует всю цепочку наследования, включая интерфейсы.

Так, приведенный пример любого объекта, следующий метод добьется цели:

bool IsTypeof<T>(object t)
{
    return (t is T);
}

Это - вид избыточных, но я полагал, что буду идти вперед и визуализировать его для всех.

, Учитывая [1 124]

var t = new Test();

следующие строки кода возвратили бы true:

bool test1 = IsTypeof<GenericInterface<SomeType>>(t);

bool test2 = IsTypeof<GenericClass<SomeType>>(t);

bool test3 = IsTypeof<Test>(t);

, С другой стороны, если Вы хотите что-то характерное для GenericClass, Вы могли бы сделать его более конкретным, я предполагаю, как это:

bool IsTypeofGenericClass<SomeType>(object t)
{
    return (t is GenericClass<SomeType>);
}

Тогда Вы протестировали бы как это:

bool test1 = IsTypeofGenericClass<SomeType>(t);
86
ответ дан EnocNRoll - Ananda Gopal 23 November 2019 в 01:48
поделиться
Type _type = myclass.GetType();
PropertyInfo[] _propertyInfos = _type.GetProperties();
Boolean _test = _propertyInfos[0].PropertyType.GetGenericTypeDefinition() 
== typeof(List<>);
0
ответ дан 23 November 2019 в 01:48
поделиться

Это может быть излишним, но я использую методы расширения, подобные следующим. Они проверяют интерфейсы, а также подклассы. Он также может возвращать тип, имеющий указанное универсальное определение.

Например, для примера в вопросе он может проверять общий интерфейс, а также универсальный класс. Возвращенный тип можно использовать с GetGenericArguments , чтобы определить, что общий тип аргумента - «SomeType».

/// <summary>
/// Checks whether this type has the specified definition in its ancestry.
/// </summary>   
public static bool HasGenericDefinition(this Type type, Type definition)
{
    return GetTypeWithGenericDefinition(type, definition) != null;
}

/// <summary>
/// Returns the actual type implementing the specified definition from the
/// ancestry of the type, if available. Else, null.
/// </summary>
public static Type GetTypeWithGenericDefinition(this Type type, Type definition)
{
    if (type == null)
        throw new ArgumentNullException("type");
    if (definition == null)
        throw new ArgumentNullException("definition");
    if (!definition.IsGenericTypeDefinition)
        throw new ArgumentException(
            "The definition needs to be a GenericTypeDefinition", "definition");

    if (definition.IsInterface)
        foreach (var interfaceType in type.GetInterfaces())
            if (interfaceType.IsGenericType
                && interfaceType.GetGenericTypeDefinition() == definition)
                return interfaceType;

    for (Type t = type; t != null; t = t.BaseType)
        if (t.IsGenericType && t.GetGenericTypeDefinition() == definition)
            return t;

    return null;
}
7
ответ дан 23 November 2019 в 01:48
поделиться

JAREDPAR,

Это не сработало для меня, если я пройдут тип (тип <>) как Tocheck. Вот что я изменил.

static bool IsSubclassOfRawGeneric(Type generic, Type toCheck) {
    while (toCheck != typeof(object)) {
        var cur = toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck;
          if (cur.IsGenericType && generic.GetGenericTypeDefinition() == cur.GetGenericTypeDefinition()) {
            return true;
        }
        toCheck = toCheck.BaseType;
    }
    return false;
}
2
ответ дан 23 November 2019 в 01:48
поделиться
Другие вопросы по тегам:

Похожие вопросы: