-1

I understand this is only possible with a workaround. But why?

I want to add plugin support to my app. So I designed an abstract class that all future plugins will need to implement. Every plugin must implement a GetVersion() method like in this example code:

public abstract class Plugin
{
    public abstract int GetVersion();
}

public class MyPlugin : Plugin
{
    public override int GetVersion()
    {
        return 1;
    }
}

This of course works perfectly as long as I instantiate the plugin before calling the GetVersion() method.

But if I want to get the version number of the plugin before creating an instance of it? To check compatibility for example?

public class Program
{
    public Program()
    {
        if (MyPlugin.GetVersion() > 1)
        {
            PluginLoader.Load(new MyPlugin());
        }
    }
}
Sandro
  • 2,998
  • 2
  • 25
  • 51
  • 1
    Inheritance makes sense when you create an instance. In other words it is for *Objects* not for classes. Even if it was possible, it will not give no gain. For example, If you need to use a static method you need to access it using the name of the class: `ClassName.Do()`, if you were allowed to inherit and override it then you will access it like: `InheritingClass.Do()` so what exactly was the gain: you still write the name of the class and the name of the method. – CodingYoshi Jul 13 '18 at 16:02
  • How are you getting the version? – sr28 Jul 13 '18 at 16:03

3 Answers3

1

Although it might not answer directly your question "WHY" I think below solution might be usefull in your scenario:

Use assembly version attribute:

  Assembly thisAssem = typeof(MyPlugin).Assembly;
  AssemblyName thisAssemName = thisAssem.GetName();

  Version ver = thisAssemName.Version;
kul_mi
  • 1,131
  • 5
  • 15
  • 33
  • This actually solves my problem. I think the best answer for the "why" comes from @CodingYoshi in the comments of the question: "Inheritance makes sense when you create an instance" – Sandro Jul 16 '18 at 07:20
0

It never can be done by C# because a static method cannot be implemented in derived classes.

Like the workaround, you can create a static factory to create the instance.

public abstract class Plugin
{
    public abstract int GetVersion();
}

public class FactoryPlugin<T> where T : Plugin, new()
{
    public static int GetVersion()
    {
        return new T().GetVersion();
    }
}

public class Program
{
    public Program()
    {
        if (FactoryPlugin<MyPlugin>.GetVersion() > 1)
        {

        }
    }
}
Antoine V
  • 6,998
  • 2
  • 11
  • 34
  • 1
    That seems even more complicated. If you force a `Plugin` to implement a `GetVersion()` method, then the static method on the factory seems unnecessary because they could just `plugin.GetVersion()` after the factory creates it. OP specifically wants the version before instantiation, but your static `GetVersion()` method is creating the object. – itsme86 Jul 13 '18 at 17:29
0

Consider using the Factory pattern in a way similar to what a COM class factory does. You create two classes, your useful class, and a class factory class. Your class factory class implements IPluginFactory. You package it with your Plugin. The plugin factory has vary simple methods, but one of them allows your Plugin to be created. It's close to what @ThierryV showed, but without static methods. So the process is:

  • Use whatever you are planning to use to store and instantiate your plugins, but instead of instantiating a plugin, you instantiate the appropriate Plugin Factory
  • You can have the Plugin factory do what ever you want -- get detailed information about the plugin, allow instantiation of the latest version or a particular version of the plugin - go to town
  • But, eventually, you use an instance of the factory to instantiate your Plugin.

This is a good place to start: What exactly is a Class Factory?, but Don Box's Essential COM book is where I learned all this stuff, a long time ago in a place far away.

Flydog57
  • 6,851
  • 2
  • 17
  • 18