views:

198

answers:

2

First let's establish this.

I have

public abstract class Foo
{
  public static void StaticMethod()
  {
  }
}
public class Bar : Foo
{
}

is it valid to call

Bar.StaticMethod();

???

If so, let's expand previous example:

public abstract class Foo
{
  public static void StaticMethod()
  {
  }
  public abstract void VirtualMethod();
}
public class Bar : Foo
{
  public override void VirtualMethod()
  {
     Trace.WriteLine("virtual from static!!!!");
  }
}

How should I construct StaticMethod in base class so I can use VirtualMethod from derived classes? It seems that I had too little/too much caffeine today and nothing comes to my mind here.

Hm, I know that I can't invoke instance method from static method. So the question comes to this:

Can I create instance of derived class from static method of base class. By using something like:

  public static void StaticMethod()
  {
    derived d=new derived();
    d.VirtualMethod();
  }

I invented new keyword, derived, for the purpose of illustration.

BTW, I will favor non-reflection based solution here!

+5  A: 

To invoke a non static method from a static method, you have to provide an instance as the static method isn't bound to this

Then, after your edit, your question made me think of the curiously recurring template pattern in C++.

I never tried myself to use it in C# but you have have a look here, which would give you something like:

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace ConsoleApplication3
{
  public abstract class Foo<T> where T : Foo<T>, new()
  {
    public static void StaticMethod()
    {
      T t = new T();
      t.VirtualMethod();
    }

    public abstract void VirtualMethod();
  }

  public class Bar : Foo<Bar>
  {
    public override void VirtualMethod()
    {
      System.Console.WriteLine("virtual from static!!!!");
    }
  }
  class Program
  {
    static void Main(string[] args)
    {
      Bar.StaticMethod();
    }
  }
}

And prints out the intended "virtual from static!!!!" message in the console.

Gregory Pakosz
I know that, of course, please check my question modification.
Daniel Mošmondor
Of course you can call non-static methods from a static method. You just have to provide an instance.
Eric Lippert
@Eric yeah right, the intent of the OP wasn't obvious before the question is edited hence my first basic answer
Gregory Pakosz
@Eric > looks like I did my homework as the same time as you did :)
Gregory Pakosz
+4  A: 

is it valid to call Bar.StaticMethod();???

Yes, calling Bar.StaticMethod is legal, and simply behaves as though you called Foo.StaticMethod.

Can I create instance of derived class from static method of base class.

OK, I think I understand what you want. You want to call a static method and have it create an instance of an ARBITRARY derived class, and then call a method on that class, yes?

Use generics.

abstract class Foo 
{
    public static void DoBlah<T>() where T : Foo, new()
    {
        T t = new T();
        t.Blah();
    }
    public abstract void Blah();
}
class Bar : Foo
{ 
    public Bar() {}
    public override void Blah() {}
}
...
Foo.DoBlah<Bar>();

Yes?

Eric Lippert
@Eric: If I call Bar.StaticMethod() I would like that method during execution to have Bar context instead of Foo context, so it can get an object instance from it and execute VirtualMethod on it.
Daniel Mošmondor
@Eric: I like Foo static method to call public constructor of Bar or Bar2 or any other descendant class, depending on the context in which is called. ie Bar.StaticMethod() should create Bar instance and Bar2.StaticMethod - Bar2 instance...
Daniel Mošmondor
@Eric: I would like to call Bar.DoBlah(); So DoBlah() will behave as a polymorphic wrapper around class instance virtual method.
Daniel Mošmondor
Then you are going to have to learn to live with your disappointment. Calling Bar.DoBlah() is exactly the same as calling Foo.DoBlah. Static methods are called static because their behaviour is STATICALLY DETERMINED by the compiler. Static is the OPPOSITE of virtual, so expecting virtual behaviour from a static method is bound to end in disappointment.
Eric Lippert
This is something that pops up quite often. I wish we could have virtual 'statics' (perhaps better called virtual class methods), like f.e. in Delphi Prism. Quite usual pattern is in ORM, where you define base persistent class, from which others derive. It makes sense to have virtual instance methods 'delete' and 'edit', but it would be quite nice to - accordingly - have virtual class method 'append' or 'insert'. I guess (mis)using dynamic in C# 4 will prove to be some kind of 'workaround'.
Dejan Stanič