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

本文关键字:子类 var 作为 期望 父类 | 更新日期: 2023-09-27 18:36:57

这是我正在尝试做的:

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; }
    }
}

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

你想如何调用SyncLists属性?

如果在另一个类中,您想消费BaseUser而不用担心它是什么子类型,那么您有理由不想担心SyncLists的子类型。在这种情况下,这就足够了。

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

和类似的EncryptedUser.

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

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>变得更加困难。

对于受保护成员覆盖基类的情况,这是无法做到的,您只需要在调用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()
    {
        //....
    }
}