ich es mit einfachen Beispiel zu erklären versuchen. Angenommen, Sie eine weitere Klasse haben Implementierung IPost<User>
:
class PicturePost : IPost<User>
{
// Implementation
}
Dann wird dieser Code nicht kompilieren:
IUser<Post> user = new User();
user.Post = new PicturePost();
Da user.Post
Betonklasse ist Post
die mit PicturePost
nicht kompatibel ist (sie Geschwister sind).
Dann diese Zeile aus Ihrer Frage vorstellen, erfolgreich kompiliert wurde:
// C# compiler is so kind today and it compiled this.
IUser<IPost<User>> user = new User();
Seit user.Post
jetzt wird der Typ sein IPost<User>
Sie möglicherweise solche Zeilen Code:
IUser<IPost<User>> user = new User();
user.Post = new PicturePost();
Und sie werden kompilieren perfekt, aber die zweite Zeile wird mit Laufzeitfehler fehlschlagen! Dies liegt daran, dass der tatsächliche Typ von user.Post
Post
nicht IPost
oder ist.
Also, um Typ-Sicherheit zu erreichen, verbietet der C# -Compiler das Kompilieren, wenn die Möglichkeit besteht, dass ein solcher Code geschrieben wird. Um sicherzustellen, dass Sie nicht einen solchen Code schreiben, sollten Post
Eigenschaft schreibgeschützt werden:
interface IUser<PostType>
{
PostType Post { get; } // No setter, this is readonly.
}
Jetzt werden Sie nicht in der Lage sein, bösen Code zu schreiben, und alle Verwendungen von Post
wird typsicher in Bezug sein von seiner Schnittstelle, da Sie nur erhalten es, und dann perfekt zuweisen Variable seiner Schnittstelle.
Aber das ist nicht genug, zu sagen, Compiler, der Ihre Schnittstelle auf der hellen Seite, müssen Sie explizit angeben, dass der Typ-Parameter ist nur aus (Sie es verwenden können, aber man kann es nicht in passieren). Also, unter Umsetzung der Schnittstelle mit (out
Stichwort bemerken), der Code kompiliert:
interface IUser<out PostType>
{
PostType Post { get; } // No setter, this is readonly.
}
// Both lines compile!
IUser<IPost<User>> user = new User();
IUser<Post> user1 = new User();
Hoffnung Ich hielt es einfach und ließ es sich nicht Punkt zur gleichen Zeit :)
können Sie beginnen [hier ] (http://blogs.msdn.com/b/ericlippert/archive/2007/10/26/covariance-and-contravariance-in-c-part-five-interface-variance.aspx) –