Mam blok kodu, który serializuje typ do tagu 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);
}
Działa to doskonale, z wyjątkiem chcę, żeby to zrobić tylko dla typów pierwotnych, jak int
, double
, bool
itp, i inne typy, które nie są prymitywne, ale może być łatwo jak serializacjistring
. Chcę, aby ignorował wszystko inne, takie jak listy i inne typy niestandardowe.
Czy ktoś może zasugerować, jak to zrobić? A może muszę określić typy, na które chcę zezwolić, i włączyć typ właściwości, aby sprawdzić, czy jest dozwolony? To trochę bałaganiarskie, więc byłoby miło, gdybym był bardziej uporządkowany.
c#
reflection
primitive-types
DaveDev
źródło
źródło
System.String
nie jest typem pierwotnym.Odpowiedzi:
Możesz użyć tej właściwości
Type.IsPrimitive
, ale zachowaj ostrożność, ponieważ są pewne typy, które możemy uważać za prymitywne, ale tak nie jest, na przykładDecimal
iString
.Edycja 1: Dodano przykładowy kod
Oto przykładowy kod:
Edycja 2: As @SLaks komentuje , istnieją inne typy, które być może chcesz również traktować jako prymitywy. Myślę, że będziesz musiał dodawać te odmiany jeden po drugim .
Edycja 3: IsPrimitive = (Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double i Single), Anther Primitive-Like type to check (t == typeof (DateTime ))
źródło
DateTime
,TimeSpan
iDateTimeOffset
.||
), a nie bitowego lub (|
).Właśnie znalazłem to pytanie, szukając podobnego rozwiązania, i pomyślałem, że możesz być zainteresowany następującym podejściem przy użyciu
System.TypeCode
iSystem.Convert
.Łatwo jest serializować dowolny typ, który jest zamapowany na
System.TypeCode
inny niżSystem.TypeCode.Object
, więc możesz zrobić:Zaletą tego podejścia jest to, że nie musisz nazywać każdego innego akceptowalnego typu niepierwotnego. Możesz również nieznacznie zmodyfikować powyższy kod, aby obsłużyć dowolny typ, który implementuje IConvertible.
źródło
Guid
do własnych celów (jako prymityw w mojej definicji).Robimy to w naszym ORM:
Wiem, że użycie
IsValueType
nie jest najlepszą opcją (możesz mieć własne bardzo złożone struktury), ale działa w 99% przypadków (i obejmuje Nullables).źródło
decimal
tym względem wszystkie struktury są podobne . Ale czy istnieje typ, dla któregoIsPrimitive
wraca,true
aleIsValueType
wracafalse
? Jeśli nie ma takiego typu,t.IsPrimitive
test jest zbędny.IsValueType
ustawioną wartość true, więc sprawdzanieIsPrimitive
nie jest konieczne. Twoje zdrowie!Z odpowiedzi @Ronnie Overby i komentarza @jonathanconway napisałem tę metodę, która działa dla Nullable i wyklucza struktury użytkownika.
Z następującym TestCase:
źródło
Enum
nie jest obsługiwane, przetestuj jeenum MyEnum { EnumValue }
i używajMyEnum
. @Jonathan też używatype.IsValueType
. Dzięki temuEnums
są poprawnie wykrywane, ale takżeStructs
. Więc uważaj, jakich prymitywów chcesz.type.IsValueType
, dlaczego po prostu nie dodaćtype.IsEnum
?type.IsEnum
jest również możliwe. Zaproponowałem zmianę w Twoim poście :)Oto jak to zrobiłem.
źródło
IsAssignableFrom
w swoim teście zamiast zawiera?Również dobra możliwość:
źródło
Type
ma właściwość o nazwie IsPrimitive . Zamiast tego powinieneś użyć tego.String
też nieDecimal
są prymitywami.Zakładając, że masz taki podpis funkcji:
Możesz dodać ogólne ograniczenie, aby zezwolić tylko na typy wartości:
Zauważ, że pozwala to nie tylko na typy pierwotne dla T, ale także na dowolny typ wartości.
źródło
Musiałem serializować typy w celu wyeksportowania ich do XML. Aby to zrobić, przeszedłem przez obiekt i wybrałem pola, które były prymitywne, wyliczeniowe, typy wartości lub możliwe do serializacji. To był wynik mojego zapytania:
Użyłem LINQ do iteracji po typach, a następnie uzyskałem ich nazwę i wartość do przechowywania w tabeli symboli. Kluczem jest klauzula „gdzie”, którą wybrałem do refleksji. Wybrałem typy prymitywne, wyliczeniowe, typy wartości i typy możliwe do serializacji. Pozwoliło to na przejście ciągów i obiektów DateTime zgodnie z oczekiwaniami.
Twoje zdrowie!
źródło
To jest to, co mam w mojej bibliotece. Komentarze są mile widziane.
Najpierw sprawdzam IsValueType, ponieważ obsługuje większość typów, a następnie String, ponieważ jest to drugi najpopularniejszy. Nie przychodzi mi do głowy prymityw, który nie jest typem wartości, więc nie wiem, czy ta noga, jeśli kiedykolwiek zostanie trafiona.
Wtedy mogę tego użyć w ten sposób:
źródło
Chcę tylko udostępnić moje rozwiązanie. Być może jest to przydatne dla każdego.
źródło
IsPrimitiveType(typeof(System.AccessViolationException)) == true
namespace System { class MyNonPrimitiveType { } }
Nie zapomnij sprawdzić przestrzeni nazw NULL, ponieważ obiekty anonimowe nie mają przypisanej przestrzeni nazw
źródło
Oto kolejna realna opcja.
źródło