派生类的C#方法作为基础构造函数中的委托

时间:2011-02-21 10:45:25

标签: c# delegates static

为什么以下C#不合法?是否有适当的解决方法?

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; }
}

5 个答案:

答案 0 :(得分:9)

它在基础构造函数的参数中有效地引用了“this”,你不能这样做。

如果您的代表确实不需要访问this(您的样本没有),您可以将其设置为静态。您还可以使用方法组转换使其更简单:

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; }
}

如果您 需要使用“this”,您可以:

  • 将其设为虚拟方法,而不是调用委托
  • 使其成为一个静态方法,采用一个合适的实例,例如

    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;
        }
    }
    

答案 1 :(得分:1)

基本上您会收到编译器错误,因为您在没有类Method的实例的情况下引用实例方法Derived。调用base时,构造函数尚未完成,您还没有类的实例。如果您制作了Method static,那就可以了。

答案 2 :(得分:1)

另一个解决方案就是将委托的初始化推迟到派生类:

public class Base {
   protected Func<double> DoubleFunc { get; set; }

   protected Base() {
      // defer initialization by not setting DoubleFunc
      // or another possibility is to set it to a dummy function:
      DoubleFunc = () => 0;
   }

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

public class Derived : Base {
   public Derived() {
      DoubleFunc = Method;
   }

   public double Method() { return 1.0; }
}

答案 3 :(得分:0)

您是否尝试过编译器指示的Method()静态?问题是Derived的实例在构造函数返回之后才可用,因此您无法在其上调用实例方法。

答案 4 :(得分:0)

“解决方法”是使Method()成为静态方法。

我无法解释为什么这不起作用的技术原因,但实际上你正试图在一个尚不存在的实例上调用一个方法。怎么可能有用?