Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

Используйте 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;

Ответ 2

Type type = typeof(Foo);

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

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


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


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

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

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

Ответ 3

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

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

public static bool IsStruct(this Type source) 
{
  return source.IsValueType && !source.IsPrimitive && !source.IsEnum;
}

Ответ 4

Попробуйте выполнить

bool IsStruct(Type t) {
  return t.IsValueType;
}

Ответ 5

Для каждого типа значений существует соответствующий автоматически сгенерированный тип класса, который происходит от 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>, будет вести себя как тип класса.