我不确定这是否可行,需要一些澄清。
我有这样的类结构:
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
这是根本无法完成的事情,还是我错过了概念/语法?
提前致谢!
答案 0 :(得分:2)
嗯,它不能直接完成 - FooBarHolderAbstract<Foo, Bar>
不是一个FooBarHolderAbstract<FooBase, BarBase>
。目前尚不清楚你是否可以逻辑拥有它,因为我们不知道抽象类中的内容。
您基本上都在寻找generic covariance,但无论如何都不支持课程 - 所以您可能想要引入一个界面:
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>
。
但是,这仅适用于您可以定义在&#34; out&#34;中使用T
和V
的界面的所有操作。职位,例如从方法返回类型。如果您在&#34;输入&#34;职位,例如作为方法参数,您会陷入困境 - 因为期望Foo
的方法无法处理任何其他类型的FooBase
。
答案 1 :(得分:1)
它不清楚,你要在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>();
}
}
答案 2 :(得分:0)
您必须如下编写FooBarTest
。您必须将T
的{{1}}定义为DoSomethingWithFooBar<T>
FooBarHolderAbstract<Foo, Bar>