cercherò di spiegarlo utilizzando semplice esempio. Supponiamo di avere una classe più attuazione IPost<User>
:
class PicturePost : IPost<User>
{
// Implementation
}
Allora questo codice non viene compilato:
IUser<Post> user = new User();
user.Post = new PicturePost();
Perché user.Post
è di classe concreta Post
che non è compatibile con PicturePost
(sono fratelli).
Poi immaginiamo che la linea dalla tua domanda è stato compilato con successo:
// C# compiler is so kind today and it compiled this.
IUser<IPost<User>> user = new User();
Dal user.Post
ora sarà di tipo IPost<User>
potenzialmente si dovrà codificare tali linee:
IUser<IPost<User>> user = new User();
user.Post = new PicturePost();
e saranno compilare perfettamente, ma la seconda riga avrà esito negativo con l'errore in fase di esecuzione! Questo perché il tipo effettivo di user.Post
è Post
non IPost
o PicturePost
.
Quindi, per ottenere la sicurezza del tipo, il compilatore C# proibisce la compilazione se esiste la possibilità che tale codice venga scritto. Al fine di garantire che non sarà possibile scrivere questo codice, Post
proprietà dovrebbe essere di sola lettura:
interface IUser<PostType>
{
PostType Post { get; } // No setter, this is readonly.
}
Ora non sarà in grado di scrivere codice maligno, e tutti gli utilizzi di Post
sarà type-safe nei confronti della sua interfaccia, dal momento che si può solo ottenere esso e che assegnare perfettamente alla variabile della sua interfaccia.
Ma questo non è sufficiente, per dire compilatore che l'interfaccia sul lato chiaro, è necessario specificare in modo esplicito che il parametro di tipo è solo fuori (si può usare, ma non si può passare in). Così, avendo seguito implementazione dell'interfaccia (si noti out
parola chiave), il codice verrà compilato:
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();
Speranza ho mantenuto semplice e non ha mancato il punto allo stesso tempo :)
Si può iniziare [qui ] (http://blogs.msdn.com/b/ericlippert/archive/2007/10/26/covariance-and-contravariance-in-c-part-five-interface-variance.aspx) –