views:

5283

answers:

6

In C#, I have base class Product and derived class Widget.

Product contains a static method MyMethod().

I want to call static method Product.MyMethod() from static method Widget.MyMethod().

I can't use the base keyword, because that only works with instance methods.

I can call Product.MyMethod() explicitly, but if I later change Widget to derive from another class, I have to revise the method.

Is there some syntax in C# similar to base that allows me to call a static method from a base class from a static method of a derived class?

+7  A: 

static methods are basically a method to fallback from object oriented concepts. As a consequence, they are not very flexible in inheritance hierarchies and it's not possible to do such a thing directly.

The closest thing I can think of is a using directive.

using mybaseclass = Namespace.BaseClass;

class MyClass : mybaseclass {

  static void MyMethod() {  mybaseclass.BaseStaticMethod();  }

}
Mehrdad Afshari
> static methods are basically a method to fallback...Why is this true?In the code for my class, the methods that rely on instance data are instance methods. The methods that don't rely on instance data, but only rely on parameters (if any) are static methods. I find this distinction useful.
A method that does not rely on an *object* instance does not play by most of the rules defined for objects (virtual method dispatching, ...).
Mehrdad Afshari
mindmodel, while there are some scenarios for it, if you start needing inheritance or [insert any other restriction vs. non static methods] it is a symptom that something else might be off ... perhaps the class have too many responsibilities
eglasius
@Freddy, my sentiments exactly. _Almost always_ when you're trying to do something the language doesn't support, then you're either using the wrong language, or trying to put a square peg in a round hole. Ruby would get @mindmodel closer to what he wants since classes are objects.
Michael Meadows
A: 

Having into account that a Static method shoudn't relay in instance data... you should have a static "MyMethod" that behaves diferent based on a parameter or something like that.

Remember that the static method defined in one class is just a way to order your code... but it is the same if that method is placed elsewhere... because it don't relay on the object where it is placed.

EDIT: I think your best choise is to use Product.MyMethod explicitly... If you think it... it should't be probable that your Widget change its base clase... and also in that case it is a minor change in code.

Romias
Not completely true. static methods can rely on private members of a type (both static and instance), as a result, they are not completely movable.
Mehrdad Afshari
True. You know the difference between static variables (one per class) and instance variables (one per instance). Why is this distinction not useful? Why it is bad OO design?
Well, I should've said that you "Should not" not relay in instance variable data... of course you "CAN". :)
Romias
A: 

Static methods are not polymorphic, so what you want to do is impossible.

Trying to find a way to treat static methods as polymorphic is possible but dangerous, because the language itself doesn't support it.

Some suggestions:

Michael Meadows
A: 

It can be done, but I don't recommend it.

public class Parent1
{
    public static void Foo()
    {
        Console.WriteLine("Parent1");
    }
}

public class Child : Parent1
{
    public new static void Foo()
    {
        Type parent = typeof(Child).BaseType;
        MethodInfo[] methods = parent.GetMethods();
        MethodInfo foo = methods.First(m => m.Name == "Foo");
        foo.Invoke(null, null);
    }
}
marcumka
Fair enough. In this case, the solution is worse than the problem. Thanks.
Exactly. Ten Characters
marcumka
nstead of using string you could useMethodBase.GetCurrentMethod().Name
Sergey Mirvoda
A: 

Static methods are "Class-Level" methods. They are intended to be methods that apply to all instances of a specific class. Thus, inheritance of this method does not make sense as it would change the meaning to apply to instances of the class. For instance, if you were looping through a collection of Products (some of Widget, some not) and called MyMethod on each Product then the method that was called would be determined by the instance of the class. This violates the purpose of static methods.

You can probably do something like you want more cleanly by simply not using static methods at all, because in your example it does not seem like MyMethod applies to all instances of Product. However, you can achieve the same affect you are describing by using an interface class like ‘IMyMethod’. This approach is still not using a static method. I guess I’m not seeing a need for a static method. Why do you want to use a static method to begin with?

Dunk
A: 

My idea is to create a Key, Value Pair Enum. Can someone comment on this approach? Especially on the static methods. Is it a good idea to overload static methods?

public class NameValueEnum<K, V>
{
    private K _key;
    private V _value;

    private static IList<NameValueEnum<K, V>> _list = new List<NameValueEnum<K, V>>();
    private NameValueEnum() { }
    public NameValueEnum(K key, V value)
    {
        this._key = key;
        this._value = value;
        _list.Add(this);
    }

    public static NameValueEnum<K, V> Parse(K key)
    {
        NameValueEnum<K, V> nve= null;
        for (int i = 0; i < _list.Count - 1; i++)
        {
            nve = _list[i];

            if (nve._key.Equals(key))
            {
                return nve;
            }
        }
        return null;
    }

    public static NameValueEnum<K, V> Parse(V value)
    {
        NameValueEnum<K, V> nve = null;
        for (int i = 0; i < _list.Count - 1; i++)
        {
            nve = _list[i];
            if (nve._value.Equals(value))
            {
                return nve;
            }
        }
        return null;
    }
}

public sealed class Status : NameValueEnum<string, Guid>
{
    public static Status Active = 
            new Status("Active", new Guid("506182B0-A123-4C21-BD2B-B758F6F635F3"));
    public static Status InActive = 
            new Status("In-Active", new Guid("D83FAFF8-69B0-4CC8-BE24-B28B47D11A01"));
    public static Status Suspended = 
            new Status("Suspended", new Guid("8FDE34CB-DB0F-47C8-B8AA-0C7D269CD0C9"));

    private Status(String Key, Guid Value) : base(Key, Value) {}

    public static new Status Parse(String key)
    {
        return (Status)NameValueEnum<String, Guid>.Parse(key);
    }

    public static new Status Parse(Guid value)
    {
        return (Status)NameValueEnum<String, Guid>.Parse(value);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Program p = new Program();
        p.f1();
    }
    private void f1()
    {
        Status s =
            Status.Parse(new Guid("506182B0-A123-4C21-BD2B-B758F6F635F3"));
    }
}