继承通用抽象
Inheriting generic abstract
我不确定这是否可行,希望得到一些说明。
我有这样的 class 结构:
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 class 中,我想创建一个接受泛型参数的方法,它继承自具有两个泛型参数的抽象 class。 class MyFooBarHolderImpl 扩展了抽象基础 class 并使用从抽象 class 的泛型参数类型继承的类型指定其泛型参数。
当我尝试调用此方法 (DoSomethingWithFooBar()) 时,编译器告诉我类型 MyFooBarHolderImpl 必须可转换为 FooBarHolderAbstract
这是根本无法完成的事情,还是我错过了 concept/syntax?
提前致谢!
嗯,这不能直接完成 - FooBarHolderAbstract<Foo, Bar>
不是 FooBarHolderAbstract<FooBase, BarBase>
。不清楚您是否可以逻辑上 拥有它,因为我们不知道摘要中的内容 class.
你基本上是在寻找 generic covariance,但 classes 不支持它 - 所以你可能想引入一个接口:
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>
.
但是,这仅在您可以为在 "out" 位置使用 T
和 V
的接口定义所有操作时才有效,例如return 来自方法的类型。如果您在 "input" 个位置需要它们,例如作为方法参数,你被卡住了——因为期望 Foo
的方法无法处理任何其他类型的 FooBase
.
您必须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>();
}
}
不清楚,你要在 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>();
}
}
我不确定这是否可行,希望得到一些说明。
我有这样的 class 结构:
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 class 中,我想创建一个接受泛型参数的方法,它继承自具有两个泛型参数的抽象 class。 class MyFooBarHolderImpl 扩展了抽象基础 class 并使用从抽象 class 的泛型参数类型继承的类型指定其泛型参数。
当我尝试调用此方法 (DoSomethingWithFooBar()) 时,编译器告诉我类型 MyFooBarHolderImpl 必须可转换为 FooBarHolderAbstract
这是根本无法完成的事情,还是我错过了 concept/syntax?
提前致谢!
嗯,这不能直接完成 - FooBarHolderAbstract<Foo, Bar>
不是 FooBarHolderAbstract<FooBase, BarBase>
。不清楚您是否可以逻辑上 拥有它,因为我们不知道摘要中的内容 class.
你基本上是在寻找 generic covariance,但 classes 不支持它 - 所以你可能想引入一个接口:
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>
.
但是,这仅在您可以为在 "out" 位置使用 T
和 V
的接口定义所有操作时才有效,例如return 来自方法的类型。如果您在 "input" 个位置需要它们,例如作为方法参数,你被卡住了——因为期望 Foo
的方法无法处理任何其他类型的 FooBase
.
您必须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>();
}
}
不清楚,你要在 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>();
}
}