Как программно проверить, является ли тип структурой или классом? - PullRequest
40 голосов
/ 01 декабря 2009

Как программно проверить, является ли тип структурой или классом?

Ответы [ 5 ]

71 голосов
/ 01 декабря 2009

Использование Type.IsValueType:

Получает значение, указывающее, является ли тип типом значения.

Используйте это так:

typeof(Foo).IsValueType

или во время выполнения, например:

fooInstance.GetType().IsValueType

И наоборот, есть также свойство Type.IsClass (которое, на мой взгляд, должно было называться IsReferenceType, но неважно), которое может подходить или не подходить для вашего использования в зависимости от того, чем вы являетесь тестирование на.

Кажется, что код всегда читается лучше без логических отрицаний, поэтому используйте любое удобство для чтения вашего кода.


Как указывает Стефан ниже, чтобы правильно определить структуры , вы должны быть осторожны, чтобы избежать ложных срабатываний, когда дело доходит до enums. enum является типом значения, поэтому свойство IsValueType вернет true для enums и structs.

Так что, если вы действительно ищете structs, а не просто типы значений в целом, вам нужно будет сделать это:

Type fooType = fooInstance.GetType();
Boolean isStruct = fooType.IsValueType && !fooType.IsEnum;
28 голосов
/ 01 декабря 2009
Type type = typeof(Foo);

bool isStruct = type.IsValueType && !type.IsPrimitive;
bool isClass = type.IsClass;

Это может быть примитивный тип или интерфейс.


Редактировать: Существует много дискуссий по поводу определения структуры. Структура и тип значения на самом деле одинаковы, поэтому IsValueType является правильным ответом. Мне обычно приходилось знать, является ли тип определенной пользователем структурой , это означает, что тип реализован с использованием ключевого слова struct, а не примитивного типа. Поэтому я сохраняю свой ответ для всех, кто сталкивается с той же проблемой, что и я.


Редактировать 2 : В соответствии с C # Reference , перечисления не являются структурами, в то время как любой другой тип значения. Следовательно, правильный ответ, как определить, является ли тип структурой:

bool isStruct = type.IsValueType && !type.IsEnum;

ИМХО, определение структуры более запутанно, чем логично. Я действительно сомневаюсь, что это определение имеет какое-либо отношение к практике.

5 голосов
/ 13 апреля 2017

Метод продления. Он возвращает true для всего, что определено как struct в моем коде, но не для таких вещей, как int, которые хотя и являются технически структурированными, не для моих целей.

Мне нужно было знать, когда тип может иметь дочерние поля или свойства, но был определен как struct, а не class. Потому что, когда вы изменяете struct, он просто изменяет копию, а затем вам нужно вернуть оригинал обратно в измененную копию, чтобы эти изменения «прилипали».

public static bool IsStruct(this Type source) 
{
  return source.IsValueType && !source.IsPrimitive && !source.IsEnum;
}
1 голос
/ 01 декабря 2009

Попробуйте следующее

bool IsStruct(Type t) {
  return t.IsValueType;
}
0 голосов
/ 26 января 2012

Для каждого типа значения существует соответствующий автоматически сгенерированный тип класса, производный от System.ValueType, который, в свою очередь, происходит от System.Object. Обратите внимание, что сами типы значений не являются производными от чего-либо, но неявно преобразуются в этот тип класса, и экземпляры этого типа класса могут быть явно преобразованы в тип значения.

Рассмотрим:

        public static int GetSomething<T>(T enumerator) where T : IEnumerator<int>
        {
            T enumerator2 = enumerator;
            enumerator.MoveNext();
            enumerator2.MoveNext();
            return enumerator2.Current;
        }

Вызов этой подпрограммы для переменной типа List<int>.Enumerator приведет к совершенно другому поведению по сравнению с вызовом ее для переменной типа IEnumerator<int>, в которой в ней хранится экземпляр List<int>.Enumerator. Даже если переменная типа List<int>.Enumerator является типом значения, экземпляр List<int>.Enumerator, хранящийся в переменной типа IEnumerator<int>, будет вести себя как тип класса.

...