Как определить тип - это настраиваемая структура?
При a Type
в С# есть свойство IsClass
, но как решить, что Type
является структурой?
Хотя IsValueType
является необходимым условием, этого явно недостаточно. Для int
также используется тип значения.
Кто-то предлагает следующий код:
bool IsStruct = type.IsValueType && !type.IsEnum && !type.IsPrimitive;
Но я не уверен, является ли он точным методом. Формула должна указывать разницу между структурными и другими типами, такими как DateTime
, int
и array
s.
Как некоторые друзья указали, что здесь я имею в виду определяемую пользователем структуру, а не предопределенные типы, такие как DateTime
.
Ответы
Ответ 1
Технически, int также является структурой. IsPrimitive просто проверяет, является ли тип одним из примитивных типов, CLR обрабатывает несколько иначе. Вы должны быть в порядке с предложением IsValueType && !IsEnum && !IsPrimitive
.
Если вам нужны только настраиваемые структуры (т.е. те, которые не предоставлены BCL), возможно, вам удастся исключить типы с полным именем, которое начинается с "System."
, или только включая те, которые вас интересуют, путем фильтрации по сборке или пространство имен или использовать пользовательский атрибут.
Ответ 2
Должно быть как минимум
bool isStruct = type.IsValueType && !type.IsEnum &&
!type.IsPrimitive && type != typeof(decimal);
Ответ 3
http://msdn.microsoft.com/en-us/library/bfft1t3c.aspx говорит:
IsValueType имеет значение true, если тип находится в {bool, byte, char, decimal, double, enum, float, int, long, sbyte, short, struct, uint, ulong, ushort}.
http://msdn.microsoft.com/en-us/library/system.type.isprimitive%28v=vs.110%29.aspx говорит:
IsPrimitive имеет значение true, если тип находится в {Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, char, Double и Single}.
Чем для IsStruct вы можете использовать такой метод:
public static bool IsStruct(this Type type)
{
return type.IsValueType
&& !type.IsPrimitive
&& !type.IsEnum
&& type != typeof(decimal);
}
Ответ 4
У вас будет непростое время с этим. Базовая платформа не знает, что все предопределенные типы в других частях Framework. Неразумно ожидать, что Core Framework знает о System.Drawing.Point
, например.
OregonGhost, вероятно, лучший answer: получите информацию о типе и проверьте свойство FullName
, чтобы узнать, начинается ли оно с "System."
. Но вам также нужно проверить "Microsoft."
и "FSharp"
и, возможно, другие. Просто нажмите "Добавить ссылку" в Visual Studio и посмотрите, какие имена появляются.
И тогда вы можете слишком сильно блокировать. Microsoft распространяет некоторые сборки через пакеты NuGet, а типы в этих сборках часто имеют имена, начинающиеся с "System."
или "Microsoft."
. Считаете ли вы эти типы "Built in", хотя они не распространяются вместе с Framework?
Ответ 5
Это сработало для меня
! x.PropertyType.IsSecurityTransparent && & x.PropertyType.IsClass
Ответ 6
Не идеальное решение, но вы всегда можете сузить поиск по известным типам внутри сборок, которые хотите найти:
System.Reflection.Assembly.GetAssembly(tyepof(OneOfMyTypes))
.GetExportedTypes()
.Where(t => t.IsValueType);
Помогает устранить ложные срабатывания (безопаснее?), но менее портативен.