Ich habe einen Codeblock, der einen Typ in ein HTML-Tag serialisiert.
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);
}
Dies funktioniert gut, außer ich will dies nur tun , für primitive Typen, wie int
, double
, bool
usw., und andere Arten , die nicht primitiv sind , aber leicht wie serialisiert werden string
. Ich möchte, dass alles andere wie Listen und andere benutzerdefinierte Typen ignoriert wird.
Kann mir jemand vorschlagen, wie ich das mache? Oder muss ich die Typen angeben, die ich irgendwo zulassen möchte, und den Typ der Eigenschaft aktivieren, um zu sehen, ob dies zulässig ist? Das ist ein bisschen chaotisch, also wäre es schön, wenn ich einen ordentlicheren Weg hätte.
c#
reflection
primitive-types
DaveDev
quelle
quelle
System.String
ist kein primitiver Typ.Antworten:
Sie können die Eigenschaft verwenden
Type.IsPrimitive
, aber seien Sie vorsichtig, da es einige Typen gibt, von denen wir glauben können, dass sie primitiv sind, aber sie sind es nicht, zum BeispielDecimal
undString
.Bearbeiten 1: Beispielcode hinzugefügt
Hier ist ein Beispielcode:
Bearbeiten 2: Wie @SLaks kommentiert, gibt es andere Typen, die Sie möglicherweise auch als Grundelemente behandeln möchten. Ich denke , dass du wirst diese Variationen hinzuzufügen haben eins nach dem anderen .
Bearbeiten 3: IsPrimitive = (Boolescher Wert, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double und Single), Anther Primitive-Like-Typ zum Überprüfen (t == typeof (DateTime) ))
quelle
DateTime
,TimeSpan
undDateTimeOffset
.||
) verwenden, nicht das bitweise oder (|
).Ich habe diese Frage gerade gefunden, als ich nach einer ähnlichen Lösung gesucht habe, und dachte, Sie könnten an dem folgenden Ansatz mit
System.TypeCode
und interessiert seinSystem.Convert
.Es ist einfach, jeden Typ zu serialisieren, der einem
System.TypeCode
anderen als zugeordnetSystem.TypeCode.Object
ist. Sie können also Folgendes tun:Der Vorteil dieses Ansatzes besteht darin, dass Sie nicht jeden anderen akzeptablen nicht-primitiven Typ benennen müssen. Sie können den obigen Code auch geringfügig ändern, um jeden Typ zu verarbeiten, der IConvertible implementiert.
quelle
Guid
für meine eigenen Zwecke hinzufügen (als Grundelement in meiner Definition).Wir machen das in unserem ORM so:
Ich weiß, dass die Verwendung
IsValueType
nicht die beste Option ist (Sie können Ihre eigenen sehr komplexen Strukturen haben), aber sie funktioniert in 99% der Fälle (und enthält Nullables).quelle
decimal
in dieser Hinsicht gleich. Aber gibt es einen Typ, für denIsPrimitive
zurückgegeben wird,true
aberIsValueType
zurückgegeben wirdfalse
? Wenn es keinen solchen Typ gibt, ist dert.IsPrimitive
Test nicht erforderlich.IsValueType
auf true gesetzt, sodassIsPrimitive
keine Überprüfung erforderlich ist. Prost!Aus der Antwort von @Ronnie Overby und dem Kommentar von @jonathanconway habe ich diese Methode geschrieben, die für Nullable funktioniert und Benutzerstrukturen ausschließt.
Mit folgendem TestCase:
quelle
Enum
nicht unterstützt. Testen Sie ihn mitenum MyEnum { EnumValue }
und verwenden Sie ihnMyEnum
. @ Jonathan verwendet auchtype.IsValueType
. Damit werden dieEnums
aber auch richtig erkanntStructs
. Achten Sie also darauf, welche Grundelemente Sie möchten.type.IsValueType
, warum nicht einfach hinzufügentype.IsEnum
?type.IsEnum
ist auch möglich. Ich habe eine Bearbeitung für Ihren Beitrag vorgeschlagen :)So habe ich es gemacht.
quelle
IsAssignableFrom
in Ihrem Test verwenden, anstatt zu enthalten?Auch eine gute Möglichkeit:
quelle
Type
hat eine Eigenschaft namens IsPrimitive . Sie sollten das stattdessen verwenden.String
nochDecimal
sind Primitive.Angenommen, Sie haben eine Funktionssignatur wie diese:
Sie können eine generische Einschränkung hinzufügen, um nur Werttypen zuzulassen:
Beachten Sie, dass dies nicht nur primitive Typen für T zulässt, sondern jeden Werttyp.
quelle
Ich musste Typen serialisieren, um sie nach XML zu exportieren. Zu diesem Zweck habe ich das Objekt durchlaufen und mich für Felder entschieden, die primitiv, enum, Werttypen oder serialisierbar waren. Dies war das Ergebnis meiner Anfrage:
Ich habe LINQ verwendet, um die Typen zu durchlaufen und dann ihren Namen und Wert in einer Symboltabelle zu speichern. Der Schlüssel liegt in der 'where'-Klausel, die ich zum Nachdenken ausgewählt habe. Ich habe primitive, aufgezählte, Werttypen und serialisierbare Typen ausgewählt. Dadurch konnten Zeichenfolgen und DateTime-Objekte wie erwartet durchlaufen werden.
Prost!
quelle
Das habe ich in meiner Bibliothek. Kommentare sind willkommen.
Ich überprüfe zuerst IsValueType, da es die meisten Typen behandelt, dann String, da es das zweithäufigste ist. Ich kann mir kein Grundelement vorstellen, das kein Werttyp ist, also weiß ich nicht, ob dieses Bein des If jemals getroffen wird.
Dann kann ich es so benutzen:
quelle
Ich möchte nur meine Lösung teilen. Vielleicht ist es für jeden nützlich.
quelle
IsPrimitiveType(typeof(System.AccessViolationException)) == true
namespace System { class MyNonPrimitiveType { } }
Vergessen Sie nicht, den NULL-Namespace zu überprüfen, da anonymen Objekten kein Namespace zugewiesen wurde
quelle
Hier ist eine weitere praktikable Option.
quelle