C # Covariance Interface

I'm not sure what is going on here, but I get a compiler error using the following code:

namespace SO
{
    interface IUser<PostType>
    {
        PostType Post { get; set; }
    }

    interface IPost<UserType>
    {
        UserType User { get; set; }
    }

    class User : IUser<Post>
    {
        //Implementation
    }

    class Post : IPost<User>
    {
        //Implementation
    }

    class SomeOtherClass
    {
        // Compiler Error: Cannot implicitly convert type 'SO.User' to
        // 'SO.IUser<SO.IPost<SO.User>>'. An explicit conversion exists 
        // (are you missing a cast?)
        IUser<IPost<User>> user = new User();

        //Works Fine
        IUser<Post> user = new User();
    }
}

Why does an error occur if it Postis a subtype IPost<User>? I know that in this case I could use Userinstead IUser<IPost<User>>, but I want to know why this is not working.

+5
source share
2 answers

I will try to explain this with a simple example. Suppose you have another class that implements IPost<User>:

class PicturePost : IPost<User>
{
    // Implementation
}

Then this code will not compile:

    IUser<Post> user = new User();
    user.Post = new PicturePost();

Because it user.Posthas a specific class Postthat is incompatible with PicturePost(they are brothers and sisters).

Then imagine that the line from your question was successfully compiled:

    // C# compiler is so kind today and it compiled this.
    IUser<IPost<User>> user = new User();

user.Post IPost<User>, :

    IUser<IPost<User>> user = new User();
    user.Post = new PicturePost();

, ! , user.Post Post IPost PicturePost.

, # , , . , , Post :

interface IUser<PostType>
{
    PostType Post { get; } // No setter, this is readonly.
}

, Post , , .

, , , , ( , ). , ( out), :

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();

, :)

+12

, covarient:

interface IUser<out PostType>
{
    PostType Post { get; }
}

interface IPost<out UserType>
{
    UserType User { get;  }
}

http://msdn.microsoft.com/en-gb/library/ee207183.aspx http://msdn.microsoft.com/en-gb/library/dd799517.aspx

0

All Articles