C#, implement 'static abstract' like methods

后端 未结 7 2036
一生所求
一生所求 2020-12-06 08:48

I recently ran into a problem where it seems I need a \'static abstract\' method. I know why it is impossible, but how can I work around this limitation?

For example

相关标签:
7条回答
  • 2020-12-06 09:26

    Combining static and abstract is somewhat meaningless, yes. The idea behind static is one need not present an instance of the class in order to use the member in question; however with abstract, one expects an instance to be of a derived class that provides a concrete implementation.

    I can see why you'd want this sort of combination, but the fact is the only effect would be to deny the implementation use of 'this' or any non-static members. That is, the parent class would dictate a restriction in the implementation of the derived class, even though there's no underlying difference between calling an abstract or 'static abstract' member (as both would need a concrete instance to figure out what implementation to use)

    0 讨论(0)
  • 2020-12-06 09:27

    A possible workaround is to define a Singleton of your derived class in your base class with the help of Generics.

    import System;
    
    public abstract class AbstractBase<T>
        where T : AbstractBase<T>, new()
    {
        private static T _instance = new T();
    
        public abstract string Description { get; }
        public static string GetDescription()
        {
            return _instance.Description;
        }
    }
    
    public class DerivedClass : AbstractBase<DerivedClass>
    {
        public override string Description => "This is the derived Class";
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(DerivedClass.GetDescription());
            Console.ReadKey();
        }
    }
    

    The trick is to tell your AbstractBase<T> some details about how DerivedClass is implemented:

    • It is newable with where T: new() so it can create a Singleton instance
    • It derives from itself with where T : AbstractBase<T> so it knows that there will be a implementation of Description

    This way _instance contains the Description field which can be called in the static Method GetDescription(). This forces you to overwrite Descriptionin your DerivedClass and allows you to call its value with DerivedClass.GetDescription()

    0 讨论(0)
  • 2020-12-06 09:40

    It's not static if it has to be called on an instance.

    If you're not calling it on an instance, then there's no polymorphism at play (i.e. ChildA.Description is completely unrelated to ChildB.Description as far as the language is concerned).

    0 讨论(0)
  • 2020-12-06 09:40

    You could make the "abstract" base method throw an Exception, so then a developer is "warned" if he tries to invoke this method on a child class without overriding.

    The downside is that one might extend the class and not use this method. Then refer to other answers provided.

    0 讨论(0)
  • 2020-12-06 09:43

    You cant.

    The place to do this is with Attributes.

    Eg

    [Name("FooClass")]
    class Foo
    {
    }
    
    0 讨论(0)
  • 2020-12-06 09:43

    If it is static, there is only one instance of the variable, I don't see how inheritance would make sense if we could do what you want to accomplish with static vars in derived classes. Personally I think you are going to far to try to avoid a instance var.

    Why not just the classic way?

    abstract class AbstractBase
    {
        protected string _Description = "I am boring abstract default value";
    }
    
    class Foo : AbstractBase {
    
         public Foo() {
           _Description = "I am foo!";
         }
    }
    
    0 讨论(0)
提交回复
热议问题