8 Stimmen

Wie kann man feststellen, ob ein .NET-Typ eine benutzerdefinierte Struktur ist?

Wie schreibt man eine einfache Methode, die prüft, ob ein konkreter Typ eine benutzerdefinierte Struktur ist (erstellt mit public struct { }; ) oder nicht.

Überprüfen Sie Type.IsValueType ist nicht genug, denn es gilt auch für int , long , usw, und das Hinzufügen eines Schecks an !IsPrimitiveType wird nicht ausschließen decimal , DateTime und vielleicht einige andere Werttypen. Ich weiß, dass die meisten der eingebauten Wertetypen eigentlich "structs" sind, aber ich möchte nur auf "custom structs" prüfen

Diese Fragen sind meist die gleichen, aber ohne die Antwort, die ich brauche:

EDIT: Von den genannten Antworten war die "Prüfung auf das Präfix 'System'" die stabilste (obwohl es immer noch ein Hack ist). Ich habe schließlich beschlossen, ein Attribut zu erstellen, mit dem man die Struktur ausschmücken muss, damit das Framework sie als benutzerdefinierte Struktur aufnimmt. (Die andere Möglichkeit, die ich in Erwägung zog, war, eine leere Schnittstelle zu erstellen und die Struktur diese leere Schnittstelle implementieren zu lassen, aber der Weg über das Attribut schien mir eleganter zu sein)

Hier ist meine ursprüngliche benutzerdefinierte Struktur Checker, wenn jemand, wenn interessiert:

type.IsValueType && !type.IsPrimitive && !type.Namespace.StartsWith("System") && !type.IsEnum

1 Stimmen

Nur aus reiner Neugierde: Warum wollen Sie das aufdecken?

0 Stimmen

Fluent NHibernate + Auto Mapping: Setzen Sie alle benutzerdefinierten Strukturen als Komponenten (Wertobjekte) behandelt werden; Einstellen eines anderen Werttyps, um eine Komponente (wie DateTime oder Dezimal) wird das gesamte Framework zum Absturz bringen (zumindest tut es unter Mono)

8voto

stusmith Punkte 13805

Es gibt keinen Unterschied zwischen einer im Framework definierten Struktur und einer von Ihnen selbst definierten Struktur.

Ein paar Ideen könnten sein:

  • Führen Sie eine Whitelist von Framework-Strukturen, und schließen Sie diese aus;
  • Identifizieren Sie die Assembly (DLL), in der der Typ definiert ist, und führen Sie eine Whitelist der Framework-Assemblies.
  • Identifizieren Sie den Namespace, in dem sich der Typ befindet, und schließen Sie den Framework-Namespace aus.

5voto

Matt Greer Punkte 58978

Nun, DateTime, decimal, etc. erfüllen Ihre Anforderungen. Soweit die CLR betroffen ist, sind sie benutzerdefinierte Strukturen. Ein Hack, aber Sie können einfach prüfen, ob der Namespace mit "System" beginnt.

3voto

GreyCloud Punkte 2950

Die obigen Bemerkungen in eine Erweiterungsmethode einfließen zu lassen:

public static class ReflectionExtensions {
        public static bool IsCustomValueType(this Type type) {            
               return type.IsValueType && !type.IsPrimitive && type.Namespace != null && !type.Namespace.StartsWith("System.");
        }
    }

sollte funktionieren

2voto

this. __curious_geek Punkte 41801

Sie können prüfen, ob der struct-Typ irgendwo innerhalb von System-Namensraum . Aber auch das ist keine zuverlässige Lösung.

-1voto

Eddy Vluggen Punkte 31

Haben Sie einen Wert, der zu diesem Typ passt? Rufen Sie die ToString Methode und prüfen Sie, ob die zurückgegebene Zeichenkette mit "{" beginnt.

Wenn Sie keinen Wert haben, prüfen Sie, ob es einen parameterlosen Konstruktor gibt. Ist dies nicht der Fall, handelt es sich um einen Konstruktor. Wenn ja, verwenden Sie die Activator um eine Instanz zu erzeugen und die ToString Methode wieder.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X