以下是我要做的事情:
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; }
}
}
答案 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()
{
//....
}
}