Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# method from derived class as delegate in base constructor

Why is the following C# not legal? Does there exist a proper workaround?

public class Base
{
    public Base(Func<double> func) { }
}

public class Derived : Base
{
    public Derived() : base(() => Method()) <-- compiler: Cannot access non-static method 'Method' in static context
    {
    }

    public double Method() { return 1.0; }
}
like image 375
NNN Avatar asked Feb 21 '11 10:02

NNN


2 Answers

It's effectively referring to "this" within the arguments to the base constructor, which you can't do.

If your delegate really doesn't need access to this (which your sample doesn't) you can just make it static. You could also use a method group conversion to make it simpler:

public class Base
{
    public Base(Func<double> func)
    {
        double result = func();
    }
}

public class Derived : Base
{
    public Derived() : base(Method)
    {
    }

    public static double Method() { return 1.0; }
}

If you do need to use "this", you could:

  • Make it a virtual method instead of calling a delegate
  • Make it a static method which takes an appropriate instance, e.g.

    public class Base
    {
        public Base(Func<Base, double> func)
        {
            double result = func(this);
        }
    }
    
    public class Derived : Base
    {
        public Derived() : base(x => Method(x))
        {
        }
    
        private static double Method(Base b) 
        {
            // The documentation would state that the method would only be called
            // from Base using "this" as the first argument
            Derived d = (Derived) b;
        }
    }
    
like image 169
Jon Skeet Avatar answered Sep 17 '22 21:09

Jon Skeet


Basically you get the compiler error because you are referencing the instance-method Method without an instance of your class Derived. When calling base, the constructor has not yet finished and you don't have an instance of your class yet. If you made Method static it would work just fine.

like image 43
Klaus Byskov Pedersen Avatar answered Sep 20 '22 21:09

Klaus Byskov Pedersen