【问题标题】:C# method from derived class as delegate in base constructor派生类中的 C# 方法作为基构造函数中的委托
【发布时间】:2011-02-21 10:45:24
【问题描述】:

为什么下面的 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; }
}

【问题讨论】:

    标签: c# delegates static


    【解决方案1】:

    它实际上是在基本构造函数的参数中引用“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;
          }
      }
      

    【讨论】:

    • 根据this的回答,这样调用基础构造函数时使用this是无效的。事实上,当我尝试它时,我得到“不能在成员初始化程序中使用'this'”错误(我相信因为 C#4)。还有其他方法吗?
    • 啊,我喜欢将引用传递给基类,然后将其转换为派生类。这对我来说并不是很明显。 +1
    【解决方案2】:

    基本上你会得到编译器错误,因为你引用了实例方法Method,而没有你的类Derived的实例。调用base 时,构造函数尚未完成,您还没有类的实例。如果你制作了Methodstatic,它会工作得很好。

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

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

          我无法解释这不起作用的技术原因,但本质上您是在尝试在尚不存在的实例上调用方法。它怎么可能起作用?

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-02-14
            • 2020-11-28
            • 2016-12-20
            • 1970-01-01
            • 2015-08-18
            • 2011-03-05
            • 1970-01-01
            • 2013-05-03
            相关资源
            最近更新 更多