Как определить тип является пользовательской структурой? - PullRequest
15 голосов
/ 19 февраля 2010

Для Type в C # есть свойство IsClass, но как определить, Type является структурой?

Хотя IsValueType является необходимым условием, этого явно недостаточно. Для int это также тип значения.

Кто-то предлагает следующий код:

bool IsStruct = type.IsValueType && !type.IsEnum && !type.IsPrimitive;

Но я не уверен, является ли это точным методом. Формула должна указывать разницу между структурой и другими типами, такими как DateTime, int и array s.

Как отметили некоторые друзья, здесь я имею в виду определяемую пользователем структуру, а не предопределенные типы , такие как DateTime.

Ответы [ 6 ]

9 голосов
/ 19 февраля 2010

Технически, int также является структурой. IsPrimitive просто проверяет, является ли тип одним из примитивных типов, которые CLR обрабатывает немного по-другому. Вы должны быть в порядке с предложением IsValueType && !IsEnum && !IsPrimitive.

Если вам нужны только пользовательские структуры (т. Е. Не предоставленные BCL), вам может повезти, за исключением типов с полным именем, начинающимся с "System.", или только тех, которые вас интересуют, путем фильтрации по сборке или пространство имен или используйте пользовательский атрибут.

2 голосов
/ 06 мая 2011

Должно быть не менее

bool isStruct = type.IsValueType && !type.IsEnum &&
               !type.IsPrimitive && type != typeof(decimal);
1 голос
/ 01 сентября 2014

http://msdn.microsoft.com/en-us/library/bfft1t3c.aspx говорит: IsValueType имеет значение true, если тип находится в {bool, байт, символ, десятичное, двойное, 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);
}
0 голосов
/ 24 октября 2017

Не идеальное решение, но вы всегда можете сузить поиск по известным типам в сборках, которые вы хотите искать:

System.Reflection.Assembly.GetAssembly(tyepof(OneOfMyTypes))
    .GetExportedTypes()
    .Where(t => t.IsValueType);

Помогает устранить ложные срабатывания (безопаснее?), Но он менее переносим.

0 голосов
/ 06 января 2016

у меня сработало ! x.PropertyType.IsSecurityTransparent && x.PropertyType.IsClass

0 голосов
/ 20 апреля 2013

Вам будет тяжело с этим.Базовая платформа не знает, что представляют собой все предопределенные типы в других частях платформы.Например, нецелесообразно ожидать, что ядро ​​Framework знает о System.Drawing.Point.

OregonGhost, вероятно, имеет лучший ответ : получите информацию о типе и проверьте свойство FullName, чтобы увидетьначинается с "System.".Но вам также нужно проверить на "Microsoft." и "FSharp", и, возможно, другие.Просто нажмите «Добавить ссылку» в Visual Studio и посмотрите, какие имена встречаются.

И тогда вы можете рискнуть заблокировать слишком много.Microsoft распространяет некоторые сборки через пакеты NuGet, и типы в этих сборках часто имеют имена, начинающиеся с "System." или "Microsoft." Считаете ли вы эти «встроенные» типы, даже если они не распространяются вместе с Framework?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...