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"
}
}
UserSyncLists
和 EncryptedUserSyncLists
都扩展了 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()
{
//....
}
}
这是我正在尝试做的事情:
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
.
有什么方法可以指定期待 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()
{
//....
}
}