我正在尝试使用通配符类型绑定在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
是第三方,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#不为类提供通用类型协方差。但这确实适用于接口。您将必须在框外思考,并为您的第3方实现一个简单的适配器SomeBindingList<T>
,该适配器仅实现协变量兼容的提升成员,即:T
仅作为输出出现的那些成员。
例如,假设SomeBindingList<T>
包含一个方法T Get()
,则可以将该成员提升到适配器接口,并创建一个简单的适配器实现。
这将是完整的代码:
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;
}
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句