18 Stimmen

Warum ist die Klasse Type nicht versiegelt, und was kann ich damit machen?

Ich habe mir die Metadaten für Type angesehen und festgestellt, dass ein Member geschützt war, was mich fragen ließ, was davon abgeleitet werden könnte, was mich erkennen ließ, dass ich eine Klasse schreiben könnte, die davon abgeleitet ist, und all das lässt mich fragen, was ich damit machen kann (wenn überhaupt).

Kein Compilerfehler bei folgendem:

class MyType : Type
{
    // Implementierte abstrakte Elemente hier.
}

1 Stimmen

Sehr interessante Frage! Bitte entfernen Sie den unnötigen Codeblock, er fügt Ihrer Frage wirklich keinen Mehrwert hinzu als nur class MyType : Type { ... }.

0 Stimmen

Ich werde es jemandem mit Bearbeitungsrechten überlassen, der mit Ihnen einverstanden ist, dies zu tun. Ich denke, es ist interessant zu sehen, was eine abgeleitete Klasse implementieren muss, um zu kompilieren...

11voto

cwharris Punkte 17356

Tolle Frage. Ich habe nur eine teilweise Antwort. Derzeit gibt es 4 Klassen, die von Type abgeleitet sind. Sie können die Typenhierarchie auf MSDN finden.

System.Object
  System.Reflection.MemberInfo
    System.Type
      System.Reflection.Emit.EnumBuilder
      System.Reflection.Emit.GenericTypeParameterBuilder
      System.Reflection.Emit.TypeBuilder
      System.Reflection.TypeDelegator

Es scheint, dass diese Typen grundsätzlich dazu verwendet werden, einige "Instanz-Erstellungs"-Logik zu kapseln. Aber ich habe den Code nicht erforscht.

Bearbeiten

Oh, wow... das ist interessant. Die Codebeispiele scheinen nicht nur Instanzen von Typen zu erstellen, sondern auch Klassen selbst. Daher erstellen einige dieser Klassen CLR-Typen und speichern sie in echten Assemblys ab. Das ist ziemlich cool.

Nochmal bearbeiten

Einige der Experten haben gesagt, dass es mehr als die vier von mir aufgelisteten Typen gibt. Ich habe Reflector ReSharper verwendet, um die abgeleiteten Typen zu finden und habe diese gefunden (es könnten immer noch fehlende Typen geben):

System.Type
  System.RuntimeType
  System.ReflectionOnlyType
  System.Reflection.Emit.EnumBuilder
  System.Reflection.Emit.GenericTypeParameterBuilder
  System.Reflection.Emit.SymbolType
  System.Reflection.Emit.TypeBuilder
  System.Reflection.Emit.TypeBuilderInstantiation
  System.Reflection.TypeDelegator

Noch einmal bearbeiten

wie @MarcGravell bereits erwähnte, gibt es wirklich keinen Grund, warum Sie eine Klasse von einer dieser Klassen ableiten möchten. Sie könnten sie jedoch innerhalb einer Klasse Ihrer eigenen verwenden, um Ihre eigene Logik zu kapseln.

1 Stimmen

Nur eine Vermutung, aber vielleicht passiert das im Hintergrund, wenn Sie einen regulären Ausdruck "vorab kompilieren".

1 Stimmen

Ja, das Meta-Programmieren ist in .NET sehr stark; Ich habe einige Codes, die wirklich verrückte Dinge damit machen.

7voto

Marc Gravell Punkte 970173

Ja, nicht von dieser Klasse erben ;p Es gibt Dinge wie RuntimeType usw. - Type ist die Abstraktion, die du normalerweise verwenden solltest. Wenn du einen Typ dynamisch zur Laufzeit darstellen möchtest, gibt es 2 Hauptoptionen;

  • In 4.0, dynamic (über die Implementierung von IDynamicMetaObjectProvider)
  • Vorher, TypeDescriptor (über die Implementierung von ICustomTypeDescriptor oder die Bereitstellung eines TypeDescriptionProvider und möglicherweise eines TypeConverter)

Wenn du Meta-Programmierung machen möchtest (tatsächlich neue Typen zur Laufzeit erstellen, anstatt sie vorzutäuschen), gibt es auch TypeBuilder

0 Stimmen

Würde es überhaupt einen Grund geben, von Typ zu erben? Die Codebeispiele auf MSDN zeigen, dass einige der abgeleiteten Typen verwendet werden, um einige Klassen erstellungslogik zu kapseln (wie z.B. den EnumBuilder). Wäre es logisch, Typ oder TypeBuilder als Basisklasse für die Generierung anderer Typen oder Assemblys zu verwenden?

0 Stimmen

@ChristopherHarris die "builder" -Versionen sind eigentlich nicht verwendbar; sie sind nur für die Metaprogrammierung gedacht. Erst wenn CreateType() verwendet wird, um einen tatsächlichen Typ (nur bekannt als Type) zu erstellen, sind sie verwendbar.

0 Stimmen

Richtig, das sehe ich jetzt. Wäre es angemessen (hypothetisch), weitere "Builder"-Versionen zu erstellen oder einfach die vorhandenen "Builder"-Versionen zu verwenden?

7voto

JaredPar Punkte 699699

Typ ist unversiegelt, weil es tatsächlich vom Runtime geerbt werden soll. Es gibt viele Beispiele dafür in der BCL.

  • EnumBuilder
  • RuntimeType
  • TypeBuilder

Das Interessanteste davon, meiner Meinung nach, ist RuntimeType. So sind die meisten Type-Instanzen in einem laufenden System implementiert. Die meisten Aufrufe von o.GetType() geben tatsächlich eine RuntimeType-Instanz zurück.

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