继承泛型抽象
本文关键字:抽象 泛型 继承 | 更新日期: 2023-09-27 18:16:57
我不确定这是否可能,寻找一些澄清。
我有一个这样的类结构:public class FooBase
{
//Some base class
}
public class BarBase
{
//Some base class
}
public class Foo : FooBase
{
//Implementation
}
public class Bar : BarBase
{
//Implementation
}
public abstract class FooBarHolderAbstract<T, V> where T: FooBase where V: BarBase
{
}
public class MyFooBarHolderImpl : FooBarHolderAbstract<Foo, Bar>
{
}
public class FooBarTest
{
public void DoSomethingWithFooBar<T>() where T : FooBarHolderAbstract<FooBase, BarBase>
{
//Do something tith the obj
}
public void RunTest()
{
//This doesn't work, compiler says MyFooBarHolder is not convertible to FooBarHolderAbstract<FooBase, BarBase>
DoSomethingWithFooBar<MyFooBarHolderImpl>();
}
}
在FooBarTest类中,我想创建一个接受泛型参数的方法,该方法继承自具有两个泛型参数的抽象类。类MyFooBarHolderImpl扩展了抽象基类,并使用继承抽象类泛型参数类型的类型指定其泛型参数。
当我尝试调用这个方法(DoSomethingWithFooBar())编译器告诉我类型MyFooBarHolderImpl必须转换为FooBarHolderAbstract
这是不能做的事情,还是我错过了一个概念/语法?
提前感谢!
嗯,这不能直接做到——FooBarHolderAbstract<Foo, Bar>
不是 FooBarHolderAbstract<FooBase, BarBase>
。不清楚你是否可以逻辑上拥有它,因为我们不知道抽象类中有什么。
你基本上是在寻找泛型协方差,但这在类上是不支持的——所以你可能想引入一个接口:
public interface IFooBarHolder<out T, out V>
where T: FooBase
where V: BarBase
{
// Define what you need in here
}
public abstract class FooBarHolderAbstract<T, V> : IFooBarHolder<T, V>
where T : FooBase
where V : BarBase
{
}
此时,您可以将FooBarTest
更改为:
public void DoSomethingWithFooBar<T>() where T : IFooBarHolder<FooBase, BarBase>
{
//Do something with the obj
}
…因为IFooBarHolder<Foo, Bar>
是和IFooBarHolder<FooBase, BarBase>
。
然而,这只有在你可以为接口定义所有使用T
和V
在"out"位置的操作时才有效,例如方法的返回类型。如果你曾经需要它们在"输入"位置,例如作为方法参数,你卡住了-因为一个方法期望Foo
不能处理任何其他类型的FooBase
。
这并不清楚,你要在DoSomethingWithFooBar
中做什么,因为你没有传递任何参数,但这里有另一个选项:
public class FooBarTest
{
public void DoSomethingWithFooBar<TFooBase, TBarBase>(FooBarHolderAbstract<TFooBase, TBarBase> obj)
where TFooBase : FooBase
where TBarBase : BarBase
{
//Do something tith the obj
}
public void RunTest()
{
DoSomethingWithFooBar<Foo, Bar>(new MyFooBarHolderImpl());
}
}
或
public class FooBarTest
{
public void DoSomethingWithFooBar<TFooBase, TBarBase, THolder>()
where TFooBase : FooBase
where TBarBase : BarBase
where THolder : FooBarHolderAbstract<TFooBase, TBarBase>
{
//Do something tith the obj
}
public void RunTest()
{
DoSomethingWithFooBar<Foo, Bar, MyFooBarHolderImpl>();
}
}
你必须写你的FooBarTest
如下。你必须将DoSomethingWithFooBar<T>
的T
定义为FooBarHolderAbstract<Foo, Bar>
public class FooBarTest
{
public void DoSomethingWithFooBar<T>() where T : FooBarHolderAbstract<Foo, Bar>
{
//Do something tith the obj
}
public void RunTest()
{
DoSomethingWithFooBar<MyFooBarHolderImpl>();
}
}