我试图找到一种从泛型基类派生类的方法。说:
sealed public class Final : Base<Something>
{
}
public class Base<T> : T
where T : Anything // <-- Generics do not allow this
{
}
在C#中,这似乎不可能。
是否还有其他解决方案可以实现类似的目标?
我发现了这个StackOverflow question,但它似乎没有解决问题,或者至少我不明白它应该如何。
修改
我想得到的结果是能够做到这样的事情:
Anything[] anything;
//Assign some Instances to anything
foreach(Final final in anything){
//do something with final
}
答案 0 :(得分:7)
The result I'd like to get is to be able to do something like that:
Anything[] anything; //Assign some Instances to anything foreach(Final final in anything){ //do something with final }
Your foreach
loop suggests this: class Anything : Final { … }
.
This obviously turns around the inheritance hierarchy as you planned and named it. (You cannot have cycles in your inheritance relationships).
public class Base<T> : T where T : Anything { …
Let me elaborate on this part for a bit. I'll reduce your example even further to just class Base<T> : T
.
This is not possible, for good reason. Imagine this:
class Base<T> : T
{
public override string Frobble()
{
Fiddle();
return "*" + base.Frobble() + "*";
}
}
class A
{
public sealed string Frobble() { … }
}
class B
{
}
class C
{
public virtual string Frobble() { … }
}
abstract class D
{
public abstract void Fiddle();
public virtual string Frobble() { … }
}
class E
{
public void Fiddle() { … }
public virtual string Frobble() { … }
}
You get all kinds of absurd situations if class Base<T> : T
were allowed.
Base<A>
would be absurd because Frobble
cannot be overridden in a derived class. Base<B>
would be absurd because you cannot override a method that
doesn't exist in the base class. Base<C>
doesn't work because there is no Fiddle
method to call.Base<D>
would not work because you cannot call an abstract method.Base<E>
would work.How would the compiler ever know how to correctly compile Base<T>
and analyse code that depends on it?
The point is that you cannot derive from a class that is not known at compile-time. T
is a parameter, i.e. a variable, a placeholder. So class Base<T> : T
is basically like saying, "Base<T>
inherits from some (unknown) class". Class inheritance is a type relationship that requires both involved types to be known at compile-time. (Actually, that's not a super-precise statement because you can inherit from a generic type such as class SpecialList<T> : List<T>
. But at the very least, the derived class has to know what members (methods, properties, etc.) are available in the base class.)
答案 1 :(得分:1)
这是你想要的吗?
sealed public class Final : Base<int>{
}
public class Base<T> {
}
答案 2 :(得分:0)
如果Final
也是一个通用类,你只能这样做,如下所示:
public sealed class Final<T> : Base<T>
然后,您可以将T
上的类型限制设为class
,仅允许引用类型为T
,或仅允许Base<T>
的实例源自Base<T>
的类型:
public class Base<T> where T : Base<T>
答案 3 :(得分:0)
我不知道这个问题的上下文,但是在一个项目中遇到了同样的问题,在这个项目中我不得不扩展已经由许多其他人派生的基类。喜欢:
abstract class Base {}
class FinalA : Base {}
class FinalB : Base {}
// Now create extended base class and expect final classes to be extended as well:
class BetterBase : Base {}
解决方案是创建公共祖先并通过属性进行连接:
abstract class Foundation {}
abstract class Base : Foundation
{
Foundation Final { get; }
}
class FinalA : Foundation {}
class FinalB : Foundation {}
class FinalC : Foundation
{
Foundation Base { get; }
}
// Here's the desired extension:
class BetterBase : Base {}
现在BetterBase可以与最终类建立连接,并且如果需要,最终类也可以与(Better)Base建立连接,如FinalC类所示。