tags:

views:

2243

answers:

4

Hello everybody !

I have the code below :

public class Anything
{
    public int Data { get; set;}
}

public class MyGenericBase<T>
{
    public void InstanceMethod(T data)
    {
        // do some job
    }

    public static void StaticMethod(T data)
    {
        // do some job
    }

    // others members...
}

public sealed class UsefulController : MyGenericBase<Anything>
{
    public void ProxyToStaticMethod()
    {
        StaticMethod(null);
    }

    // others non derived members...
}

public class Container
{
    public UsefulController B { get; set; }
}

public class Demo
{
    public static void Test()
    {
        var c = new Container();
        c.B.InstanceMethod(null);   // Works as expected.
        c.B.StaticMethod(null);     // Doesn't work. 
                                    // Static method call on object rather than type. 
                                    // How to get the static method on the base type ?
        c.B.ProxyToStaticMethod();  // Works as expected.
    }
}

The compiler is very angry... I understand the error message but I don't know how to solve this. I was trying to get a type rather than an object to make my static method call, but I don't find the way to do it correctly. Moreover this results in something not elegant at all.

Basically, the GenericBase is a class from a framework with a lot of static methods and some instance methods. The controller is typing this class and extending it.

The container is a group of logical related controllers.

Interesting thing : a Java version of this code compiles correctly, but with a warning. The execution is correct, too.

Does it exist a design pattern to solve this ?

Thanks for your inputs !


I found a way to get rid of this problem, thanks to your answers. It seems to work, but I can not tell if there are side effects right know.

    public class GenericBase<T> : MyGenericBase<T>
{
 // Create instance calls here for every base static method.
}

public sealed class UsefulController : GenericBase<Anything>
{
 // others non derived members...
}
+4  A: 

A call to a static method will be compiled to call a specific static method on a specific class. In other words, it won't use the contents of B to determine which static method to call.

So the call has to be resolvable at compile time, hence it complains, because for all it knows, you could replace the contents of that property with multiple concrete types, which would mean that the call to the static method would have to be resolved to a static method in either of these classes.

The compiler does not have anything like a virtual or abstract static method, so for one you can't guarantee that all of those classes have that static method. And since the call has to be resolvable at compile time, it won't work like that.

You can, as you've noticed, call an instance method of the object, which in turn calls the static method. This does not invalidate the above rules since when the compiler compiles that instance method, which static method it will call is constant and known.

Lasse V. Karlsen
Very instructive, thanks ! Reading answers below, I am wondering about a possible solution. Feel free to comment.
Surf-O-Matic
after all, they're not called STATIC for nothing
BlackTigerX
+2  A: 

You can't do this in C#. You can do it in VB.NET and Java, but honestly, it doesn't really make sense. It just gives you a false sense of polymorphism in a static method, which is not real by any means. Since it's not polymorphic, the whole method call is known at compile time (statically) and you could mention the call directly with the class name.

Mehrdad Afshari
+1  A: 

To call the static method you need to refer to it from the class it's defined in, not an instance of that class.

 MyGenericBase<Anything>.StaticMethod( null );
tvanfosson
Thanks ! I already noticed this. I am looking for a way to make these calls through the container. What would you think to derive first the base class to another base that would include instance calls to static methods, then to derive from it ?
Surf-O-Matic
A: 

You can do one of those:

UsefulController.StaticMethod(null);  
MyGenericBase<Anything>.StaticMethod(null);

Using the instance is not possible, as already explained by others.

Lucero
Thanks ! I already noticed this. I am looking for a way to make these calls through the container. What would you think to derive first the base class to another base that would include instance calls to static methods, then to derive from it ?
Surf-O-Matic
If you think that you "need" this instance call, just add your proxy method. My advice is just to try and keep the API clean and unambiguous.
Lucero
As I cannot directly call static members using the containing class, it seems that it is the only solution for now. I agree to keep the API as clean as possible.
Surf-O-Matic