C# Define base class by

后端 未结 4 1048
耶瑟儿~
耶瑟儿~ 2021-01-14 03:11

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

        
相关标签:
4条回答
  • 2021-01-14 03:15

    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.
    • Only 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.)

    0 讨论(0)
  • 2021-01-14 03:21

    Is this what you want?

    sealed public class Final : Base<int>{
    
    }
    
    public class Base<T> {
    
    }
    
    0 讨论(0)
  • 2021-01-14 03:28

    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.

    0 讨论(0)
  • 2021-01-14 03:39

    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>
    
    0 讨论(0)
提交回复
热议问题