У меня есть блок кода, который сериализует тип в тег HTML.
Type t = typeof(T); // I pass <T> in as a paramter, where myObj is of type T
tagBuilder.Attributes.Add("class", t.Name);
foreach (PropertyInfo prop in t.GetProperties())
{
object propValue = prop.GetValue(myObj, null);
string stringValue = propValue != null ? propValue.ToString() : String.Empty;
tagBuilder.Attributes.Add(prop.Name, stringValue);
}
Это прекрасно работает, за исключением того, что я хочу, чтобы это делалось только для примитивных типов, например int
, double
и bool
т. Д., А также для других типов, которые не являются примитивными, но могут быть легко сериализованы, например string
. Я хочу, чтобы он игнорировал все остальное, например списки и другие пользовательские типы.
Кто-нибудь может подсказать, как мне это сделать? Или мне нужно указать типы, которые я хочу разрешить где-нибудь, и включить тип свойства, чтобы узнать, разрешено ли оно? Это немного грязно, так что было бы хорошо, если бы я был более аккуратным способом.
c#
reflection
primitive-types
DaveDev
источник
источник
System.String
это не примитивный тип.Ответы:
Вы можете использовать это свойство
Type.IsPrimitive
, но будьте осторожны, потому что есть некоторые типы, которые мы можем рассматривать как примитивы, но это не так, например,Decimal
иString
.Редактировать 1: Добавлен пример кода
Вот пример кода:
Изменить 2: Как комментарии @SLaks , есть и другие типы, которые, возможно, вы также хотите рассматривать как примитивы. Я думаю, что вы должны будете добавить эти варианты один за другим .
Изменить 3: IsPrimitive = (логическое значение, байт, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double и Single), тип, аналогичный пыльниковому примитиву, для проверки (t == typeof (DateTime) ))
источник
DateTime
,TimeSpan
иDateTimeOffset
.||
), а не побитовое или (|
).Я только нашел этот вопрос, когда искал похожее решение, и подумал, что вас может заинтересовать следующий подход с использованием
System.TypeCode
иSystem.Convert
.Легко сериализовать любой тип, который сопоставлен с
System.TypeCode
другимSystem.TypeCode.Object
, поэтому вы можете сделать:Преимущество этого подхода заключается в том, что вам не нужно называть любой другой приемлемый не примитивный тип. Вы также можете немного изменить приведенный выше код для обработки любого типа, который реализует IConvertible.
источник
Guid
для собственных целей (как примитив в моем определении).Мы делаем это так в нашем ORM:
Я знаю, что использование
IsValueType
не лучший вариант (у вас могут быть свои очень сложные структуры), но он работает в 99% случаев (включая Nullables).источник
decimal
в этом отношении. Но есть ли тип, для которогоIsPrimitive
возвращается,true
ноIsValueType
возвращаетсяfalse
? Если такого типа нет, тогдаt.IsPrimitive
проверка не нужна.IsValueType
значение true, поэтому проверкаIsPrimitive
не нужна. Ура!Из ответа @Ronnie Overby и комментария @jonathanconway я написал этот метод, который работает для Nullable и исключает пользовательские структуры.
Со следующим TestCase:
источник
Enum
он не поддерживается, протестируйте егоenum MyEnum { EnumValue }
и используйтеMyEnum
. @Jonathan также используетtype.IsValueType
. При том, чтоEnums
они правильно обнаружены, но иStructs
. Так что следите, какие примитивы вы хотите.type.IsValueType
, чтобы использовать , почему бы просто не добавитьtype.IsEnum
?type.IsEnum
тоже возможно. Я предложил изменить ваше сообщение :)Вот как я это сделал.
источник
IsAssignableFrom
в своем тесте вместо содержимого?Также хорошая возможность:
источник
Type
имеет свойство с именем IsPrimitive . Вы должны использовать это вместо этого.String
ниDecimal
примитивы.Предполагая, что у вас есть подпись функции, подобная этой:
Вы можете добавить общее ограничение, чтобы разрешить только типы значений:
Обратите внимание, что это допускает не только примитивные типы для T, но и любой тип значения.
источник
Мне нужно было сериализовать типы для экспорта в XML. Для этого я перебрал объект и выбрал поля, которые были примитивами, перечислениями, типами значений или сериализуемыми. Это был результат моего запроса:
Я использовал LINQ, чтобы перебрать типы, а затем получить их имя и значение для хранения в таблице символов. Ключ в предложении «где», которое я выбрал для размышления. Я выбрал примитивные, перечислимые, типы значений и сериализуемые типы. Это позволило проходить строки и объекты DateTime, как я и ожидал.
Ура!
источник
Это то, что у меня есть в моей библиотеке. Комментарии приветствуются.
Сначала я проверяю IsValueType, поскольку он обрабатывает большинство типов, затем String, поскольку он является вторым по распространенности. Я не могу думать о примитиве, который не является типом значения, поэтому я не знаю, будет ли когда-нибудь поражена эта нога.
Тогда я могу использовать это так:
источник
Я просто хочу поделиться своим решением. Возможно, это полезно для всех.
источник
IsPrimitiveType(typeof(System.AccessViolationException)) == true
namespace System { class MyNonPrimitiveType { } }
Не забудьте проверить NULL пространство имен, потому что анонимные объекты не имеют назначенного пространства имен
источник
Вот еще один жизнеспособный вариант.
источник