我正在尝试使用通配符类型绑定(bind)在 C# 中做一些在 Java 中非常简单的事情。我试图将其归结为仅说明问题(编译)所必需的 Java 代码:
public abstract class ParentClass {
public abstract SomeBindingList<? extends ParentClass> parentList();
}
public class ChildClass extends ParentClass {
private SomeBindingList<ChildClass> myList;
public ChildClass() {
// this could load from/bind to a database
myList = new SomeBindingList<ChildClass>();
}
public SomeBindingList<? extends ParentClass> parentList() {
return myList;
}
}
也许我需要强调以下行,因为有人将其标记为重复:
<强> SomeBindingList
是第 3 方 BindingList
所以我不能改变它。它是参数化的,不能用非参数化版本替换。
问题当然是如何实现parentList()
ChildClass
中的方法返回可用作 ParentClass
列表的列表对象。
似乎应该有一些方法可以使用 where
关键字在 C# 中提供受限类型,但我无法(至少在语法上)使它与已经扩展另一个类的类一起工作,即 ChildClass
,并且似乎没有一种方法可以仅参数化方法(或属性)的返回值。
我可以制作一个新列表并放入所有 ChildClass
新列表中的项目为 ParentClass
项,但是(除了笨拙之外)我担心这会干扰 SomeBindingList
的行为.
我不是 C# 专家,所以我相信更熟悉该语言的人知道答案。谢谢!
@CodeCaster——我已经尝试了很多 C# 代码的变体(这不能编译,而且我找不到可以编译的变体):
public abstract class ParentClass {
public abstract List<T> parentList<T>() where T : ParentClass;
}
public class ChildClass {
public List<ChildClass> myList;
public ChildClass() {
myList = new List<ChildClass>();
}
public override List<T> parentList<T>() where T : ParentClass {
return myList;
}
}
我试过参数化 ChildClass<T>
但这只会导致生成 List<ChildClass<T>>
这不是 List<T>
最佳答案
我认为您的问题与通用第 3 方的继承层次结构之间关系的所需协方差有关 SomeBindingList<T>
类和用作参数的类型的层次结构。
首先,让我给你编译代码:
public interface ISomeBindingList<out T>
{
}
public abstract class ParentClass
{
public abstract ISomeBindingList<ParentClass> parentList();
}
public class ChildClass : ParentClass
{
private ISomeBindingList<ChildClass> myList;
public ChildClass()
{
// this could load from/bind to a database
// myList = new SomeBindingList<ChildClass>(); // <-- we need to figure out this
}
public override ISomeBindingList<ParentClass> parentList()
{
return myList;
}
}
C# 不为类提供通用类型协变。但它适用于接口(interface)。您将不得不跳出框框思考并为您的第 3 方实现一个简单的适配器 SomeBindingList<T>
,它仅实现协变兼容的提升成员,即:那些成员 T
仅作为输出出现。
例如,假设 SomeBindingList<T>
包含一个方法 T Get()
,您将将此成员提升为适配器接口(interface),并创建一个简单的适配器实现。
这是完整的代码:
public interface ISomeBindingList<out T>
{
T Get();
}
public class SomeBindingListAdapter<T> : SomeBindingList<T>, ISomeBindingList<T>
{
}
public abstract class ParentClass
{
public abstract ISomeBindingList<ParentClass> parentList();
}
public class ChildClass : ParentClass
{
private ISomeBindingList<ChildClass> myList;
public ChildClass()
{
// this could load from/bind to a database
myList = new SomeBindingListAdapter<ChildClass>();
}
public override ISomeBindingList<ParentClass> parentList()
{
return myList;
}
}
关于C# 集合类型约束泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24440173/