I am trying to find a way to derive a class from a generic base class. Say:
sealed public class Final : Base
{
}
public class Base
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.)
Is this what you want?
sealed public class Final : Base<int>{
}
public class Base<T> {
}
I don't know the context of this question, but I ran into same question with a project where I had to make it possible to extend the base class which is already derived by many others. Like:
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 {}
The solution was to create common ancestor and connect through properties:
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 {}
Now BetterBase has connection to final class and if needed, the final classes could have connection with (Better)Base also, as shown in FinalC class.
You could only do this if Final
would be a generic class as well, like so:
public sealed class Final<T> : Base<T>
Then you can put a type restraint on T
as either a class
, to allow only reference types as T
, or an instance of Base<T>
, to allow only types that derive from Base<T>
:
public class Base<T> where T : Base<T>