父类期望var为T,子类将var作为T的子级

时间:2015-01-08 14:31:06

标签: c# inheritance

以下是我要做的事情:

public class BaseUser
{
    protected virtual SyncLists SyncLists
    {
        get { return null; }
    }
}

public class User : BaseUser
{
    protected override UserSyncLists SyncLists
    {
        get { return new UserSyncLists(); } //Error: "Type must be SyncLists"
    }
}

public class EncryptedUser : BaseUser
{
    protected override EncryptedUserSyncLists SyncLists
    {
        get { return new EncryptedUserSyncLists(); } //Error: "Type must be SyncLists"
    }
}

UserSyncListsEncryptedUserSyncLists都延伸SyncLists

有没有办法指定期望儿童班?有点像:

public class BaseUser
{
    protected virtual (Children of)SyncLists SyncLists
    {
        get { return null; }
    }
}

3 个答案:

答案 0 :(得分:3)

您想如何调用SyncLists财产?

如果在另一个课程中,您想要使用BaseUser而不担心它是什么子类型,那么您可能不想担心SyncLists的子类型。在这种情况下,这就足够了。

public class User : BaseUser
{
    protected override SyncLists SyncLists
    {
        get { return new UserSyncLists(); }
    }
}

EncryptedUser类似。

答案 1 :(得分:1)

您可以尝试将返回类型作为通用参数传递:

public class BaseUser<T> where T : SyncLists
{
    protected virtual T SyncLists
    {
        get { return default(T); }
    }
}

然后:

public class User : BaseUser<UserSyncLists>
{
    protected override UserSyncLists SyncLists
    {
        get { return new UserSyncLists(); }
    }
}

请注意,如果您只想抽象出去,您可以随时使用基类SyncList并简单地返回一个更加派生的类型,并在每次想要查看它是否是子对象时进行转换(尽管如此可以变得麻烦)。虽然如果你问这个,我假设你想直接处理子对象。

另外,正如@Scot所提到的,这将使得使用IEnumerable<BaseUser>变得更加困难。

答案 2 :(得分:0)

对于覆盖基类的受保护成员的情况,无法完成,只需要在调用SyncLists的类中进行强制转换。但是,如果您遇到与界面和公共成员类似的情况,则可以完成。

您需要做的就是使用“更通用”版本的显式接口实现,然后让您自己的类公开其特定版本。

public interface IUser
{
    SyncLists SyncLists { get; }
}

public class User : IUser
{
    SyncLists IUser.SyncLists
    {
        get { return SyncLists; }
    }

    public UserSyncLists SyncLists
    {
        get { return new UserSyncLists();}
    }
}

public class EncryptedUser : IUser
{
    SyncLists IUser.SyncLists
    {
        get { return SyncLists; }
    }

    public EncryptedUserSyncLists SyncLists
    {
        get { return new EncryptedUserSyncLists(); }
    }
}

这与您在使用IEnumerable<T>同时实施IEnumerator GetEnumorator()IEnumerator<T> GetEnumerator()

时通常实施的模式相同
public class Foo : IEnumerable<Bar>
{
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public IEnumerator<Bar> GetEnumerator()
    {
        //....
    }
}