views:

1018

answers:

6

Hi,

Why is static virtual impossible? Is C# dependent or just don't have any sense in the OO world?

I know the concept has already been underlined but I did not find a simple answer to the previous question.

Thx

+16  A: 

virtual means the method called will be chosen at run-time, depending on the dynamic type of the object. static means no object is necessary to call the method.

How do you propose to do both in the same method?

sbi
we don't call them functions :) we call them methods
Yassir
@Yassir: Ah, thanks. Outing me as being the C++ guy here. :) I'll correct this.
sbi
I wouldlike to do something like this :((I)typeof(mybject)).MyStaticFunction(with I, an interface with MyStaticFunction a static function of the interface)I know the syntax is incorrect but here is the point.
Toto
You cannot do that, as static methods aren't inherited.
Dykam
+1  A: 

Changes are, if you think you need virtual static methods, you likely need to change how you are looking at the problem. What problem are you trying to solve with virtual static methods?

Richard Szalay
+1  A: 

In .NET, virtual method dispatch is (roughly) done by looking at the actual type of an object when the method is called at runtime, and finding the most overriding method from the class's vtable. When calling on a static class, there is no object instance to check, and so no vtable to do the lookup on.

thecoop
+5  A: 

Eric Lippert has a blog post about this, and as usual with his posts, he covers the subject in great depth:

http://blogs.msdn.com/ericlippert/archive/2007/06/14/calling-static-methods-on-type-variables-is-illegal-part-one.aspx

“virtual” and “static” are opposites! “virtual” means “determine the method to be called based on run time type information”, and “static” means “determine the method to be called solely based on compile time static analysis”

Michael Stum
A: 

While technically its not possible to define a static virtual method, for all the reasons already pointed out here, you can functionally accomplish what I think your trying using C# extension methods.

From MSDN:

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.

Check out C# Extension Methods (C# Programming Guide) for more details.

Zach Bonham
+2  A: 

I'm going to be the one who naysays. What you are describing is not technically part of the language. Sorry. But it is possible to simulate it within the language.

Let's consider what you're asking for - you want a collection of methods that aren't attached to any particular object that can all be easily callable and replaceable at run time or compile time.

To me that sounds like what you really want is a singleton object with delegated methods.

Let's put together an example:

public interface ICurrencyWriter {
    string Write(int i);
    string Write(float f);
}

public class DelegatedCurrencyWriter : ICurrencyWriter {
    public DelegatedCurrencyWriter()
    {
        IntWriter = i => i.ToString();
        FloatWriter = f => f.ToString();
    }
    public string Write(int i) { return IntWriter(i); }
    public string Write(float f) { return FloatWriter(f); }
    public Func<int, string> IntWriter { get; set; }
    public Func<float, string> FloatWriter { get; set; }
}

public class SingletonCurrencyWriter {
    public static DelegatedCurrencyWriter Writer {
        get {
            if (_writer == null)
               _writer = new DelegatedCurrencyWriter();
            return _writer;
        }
    }
}

in use:

Console.WriteLine(SingletonCurrencyWriter.Writer.Write(400.0f); // 400.0

SingletonCurrencyWriter.Writer.FloatWriter = f => String.Format("{0} bucks and {1} little pennies.", (int)f, (int)(f * 100));

Console.WriteLine(SingletonCurrencyWriter.Writer.Write(400.0f); // 400 bucks and 0 little pennies

Given all this, we now have a singleton class that writes out currency values and I can change the behavior of it. I've basically defined the behavior convention at compile time and can now change the behavior at either compile time (in the constructor) or run time, which is, I believe the effect you're trying to get. If you want inheritance of behavior, you can do that to by implementing back chaining (ie, have the new method call the previous one).

That said, I don't especially recommend the example code above. For one, it isn't thread safe and there really isn't a lot in place to keep life sane. Global dependence on this kind of structure means global instability. This is one of the many ways that changeable behavior was implemented in the dim dark days of C: structs of function pointers, and in this case a single global struct.

plinth