Parent class 期望 var 作为 T,child class 给出 var 作为 T 的 child

Parent class expecting var as T, child class gives var as child of T

这是我正在尝试做的事情:

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.

有什么方法可以指定期待 children 类?大致如下:

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

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

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 并简单地 return 一个更派生的类型,并在每次您想查看它是否属于一个子对象(尽管这会变得很麻烦)。虽然如果你问这个,我假设你想直接处理子对象。

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

你想怎么称呼 SyncLists 属性?

如果在另一个 class 中,您想使用 BaseUser 而不必担心它是什么子类型,那么按理说您不想担心 SyncLists。在这种情况下,这就足够了。

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

以及 EncryptedUser 的类似内容。

对于受保护成员覆盖基数 class 的情况,这是无法完成的,您只需要在调用 SyncLists 的 class 内部进行转换。但是,如果您的界面和 public 成员处于类似情况,则可以完成。

您需要做的就是使用 "more generic" 版本的显式接口实现,然后让您自己的 classes 公开其特定版本。

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()
    {
        //....
    }
}