sagte Juan Manuel:
Das ist einer der Gründe, warum ich nicht verstehe, warum es nicht Teil des Vertrags in der Schnittstelle sein kann.
Es ist ein indirekter Mechanismus. Die Generik erlaubt es Ihnen, zu "schummeln" und Typinformationen zusammen mit der Schnittstelle zu senden. Das Entscheidende dabei ist, dass sich die Einschränkung nicht auf die Schnittstelle bezieht, mit der Sie direkt arbeiten. Es handelt sich nicht um eine Einschränkung für die Schnittstelle selbst, sondern für einen anderen Typ, der auf der Schnittstelle "mitfährt". Das ist leider die beste Erklärung, die ich anbieten kann.
Zur Veranschaulichung dieser Tatsache möchte ich auf eine Lücke hinweisen, die ich im Code von aku festgestellt habe. Es ist möglich, eine Klasse zu schreiben, die sich gut kompilieren lässt, aber zur Laufzeit nicht funktioniert, wenn man versucht, sie zu instanziieren:
public class Something : ITest<String>
{
private Something() { }
}
Etwas leitet sich von ITest<T> ab, implementiert aber keinen parameterlosen Konstruktor. Es wird gut kompiliert, weil String einen parameterlosen Konstruktor implementiert. Auch hier gilt die Einschränkung für T und damit für String, und nicht für ITest oder Something. Da die Einschränkung auf T erfüllt ist, wird dies kompiliert. Aber es wird zur Laufzeit fehlschlagen.
Zu verhindern einige Instanzen dieses Problems, müssen Sie eine weitere Bedingung zu T hinzufügen, wie unten:
public interface ITest<T>
where T : ITest<T>, new()
{
}
Beachten Sie die neue Einschränkung: T : ITest<T>. Diese Einschränkung legt fest, dass das, was Sie in den Argument-Parameter von ITest<T> übergeben muss auch ableiten. von ITest<T>.
Dennoch wird dies nicht verhindern, dass alle Fälle des Lochs. Der folgende Code lässt sich gut kompilieren, da A einen parameterlosen Konstruktor hat. Aber da der parameterlose Konstruktor von B privat ist, wird die Instanziierung von B mit Ihrem Prozess zur Laufzeit fehlschlagen.
public class A : ITest<A>
{
}
public class B : ITest<A>
{
private B() { }
}