Es gibt bestimmte Klassen im Framework, die spezielle Merkmale effektiv an alle von ihnen abgeleiteten Typen weitergeben, diese Merkmale jedoch selbst nicht besitzen . Die CLR selbst schreibt nicht vor, diese Klassen als Einschränkungen zu verwenden, aber auf sie beschränkte generische Typen würden die nicht vererbten Merkmale nicht wie konkrete Typen erhalten. Die Entwickler von C # entschieden, dass sie solche Einschränkungen verbieten sollten, anstatt ihnen zu erlauben, sich so zu verhalten, wie sie es in der CLR tun, da ein solches Verhalten einige Menschen verwirren könnte und sie keinen Nutzen daraus ziehen konnten.
Wenn man zum Beispiel schreiben darf : void CopyArray<T>(T dest, T source, int start, int count)
; man könnte Methoden dest
und source
Methoden übergeben, die ein Argument vom Typ erwarten System.Array
; Ferner würde eine Kompilierung-Validierung , dass bekommen dest
und source
waren die kompatibelen Array - Typen, aber man würde nicht dem Zugriff auf Elemente des Arrays mit der Lage sein []
Bediener.
Die Unfähigkeit, Array
als Einschränkung zu verwenden, ist meistens recht einfach zu umgehen, da dies void CopyArray<T>(T[] dest, T[] source, int start, int count)
in fast allen Situationen funktioniert, in denen die erstere Methode funktionieren würde. Es hat jedoch eine Schwäche: Die erstere Methode würde in dem Szenario funktionieren, in dem eines oder beide der Argumente vom Typ waren, System.Array
während Fälle zurückgewiesen wurden, in denen die Argumente inkompatible Array-Typen sind. Durch Hinzufügen einer Überladung, bei der beide Argumente vom Typ waren, System.Array
würde der Code die zusätzlichen Fälle akzeptieren, die er akzeptieren sollte, aber auch fälschlicherweise Fälle akzeptieren, die er nicht akzeptieren sollte.
Ich finde die Entscheidung, die meisten besonderen Einschränkungen zu verbieten, lästig. Die einzige, die keine semantische Bedeutung haben würde, wäre System.Object
[denn wenn dies als Einschränkung legal wäre, würde alles sie erfüllen]. System.ValueType
Dies wäre wahrscheinlich nicht sehr nützlich, da Referenzen vom Typ ValueType
nicht wirklich viel mit Werttypen gemeinsam haben, aber in Fällen, in denen es um Reflexion geht, plausibel einen gewissen Wert haben könnten. Beide System.Enum
und System.Delegate
hätten einige echte Verwendungszwecke, aber da die Macher von C # nicht an sie gedacht haben, sind sie ohne guten Grund verboten.