父类期望 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"
}
}
UserSyncLists
和EncryptedUserSyncLists
都扩展了SyncLists
。
有什么方法可以指定期望儿童课程吗?大致如下:
public class BaseUser
{
protected virtual (Children of)SyncLists SyncLists
{
get { return null; }
}
}
你想如何调用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()
{
//....
}
}