【问题标题】:C# Abstract Func assignment (delegates)C# 抽象函数赋值(委托)
【发布时间】:2019-01-28 08:42:19
【问题描述】:

我有以下抽象函数。

public abstract Func<IEnumerable<TInput>, int, TIndexed> IndexedObjectConstructor { get; }

我的问题与实现方法有关。 第一个:我创建了一个具有相同签名的方法

 public  IIndexedOhlcv Test(IEnumerable<IOhlcv> l, int i)
        {
            return new IndexedCandle(l, i);
        } 

,将其分配给 Func。

 public override Func<IEnumerable<IOhlcv>, int, IIndexedOhlcv> IndexedObjectConstructor = Test;

但是,这显示一个错误

错误 CS0106 修饰符“覆盖”对此项无效

我知道这可以使用 Lambda 解决,如下所示:

 public override Func<IEnumerable<IOhlcv>, int, IIndexedOhlcv> IndexedObjectConstructor => Test;

或者

  public override Func<IEnumerable<IOhlcv>, int, IIndexedOhlcv> IndexedObjectConstructor
           => (l, i) => new IndexedCandle(l, i);

我的问题是我的“IndexedObjectConstructor = Test;”不工作?

【问题讨论】:

  • minimal reproducible example 在这里会很棒。我想复制、粘贴和编译你的代码。
  • 为什么是抽象的 Func?
  • 为什么要将 Func 作为抽象?
  • 它不是abstract Func - 它是一个abstract 属性,它返回一个Func

标签: c# delegates func


【解决方案1】:

IndexedObjectConstructor 是一个 get-only 属性,它返回一个 Func&lt;IEnumerable&lt;TInput&gt;, int, TIndexed&gt;。在您尝试的覆盖中,您定义了一个字段 IndexedObjectConstructor,您尝试使用 Test 对其进行初始化。

字段不能被覆盖(即使它们可以被覆盖,它也是基类中的一个属性,而不是一个字段)并且Test 本身也不是一个属性获取器。

当您“使用 lambda”实现它时,您使用的是相对较新的 inline property declaration 语法。

【讨论】:

    【解决方案2】:

    这是因为被覆盖的东西是一个属性,这意味着你必须在覆盖时声明一个get 访问器,而在你这样做时不会这样做

    public override Func<IEnumerable<IOhlcv>, int, IIndexedOhlcv> IndexedObjectConstructor = Test;
    

    它还解释了以下工作的原因

    public override Func<IEnumerable<IOhlcv>, int, IIndexedOhlcv> IndexedObjectConstructor => Test;
    

    【讨论】:

    • 第二个是什么意思?只实现get访问器类似吗?
    • 是的,这是一种捷径,还有其他方法可以做到这一点,例如public override Func&lt;IEnumerable&lt;IOhlcv&gt;, int, IIndexedOhlcv&gt; IndexedObjectConstructor { get =&gt; Test; }
    【解决方案3】:

    您不能只将方法分配给属性。您需要完全实现get

    您的代码需要如下所示:

    public override Func<IEnumerable<IOhlcv>, int, IIndexedOhlcv> IndexedObjectConstructor
    {
        get
        {
            return (xs, i) => Test(xs, i);
        }
    }
    

    不过,像这样使用较新的语法就足够了:

    public override Func<IEnumerable<IOhlcv>, int, IIndexedOhlcv> IndexedObjectConstructor
    {
        get => Test;
    }
    

    ...或者这个:

    public override Func<IEnumerable<IOhlcv>, int, IIndexedOhlcv> IndexedObjectConstructor
        => Test;
    

    【讨论】:

      【解决方案4】:

      这是完整的工作示例。

      public abstract class Test<TInput, TIndexed>
          {
              public abstract Func<IEnumerable<TInput>, int, TIndexed> IndexedObjectConstructor { get; }
          }
      
          public class Test1 : Test<IOhlcv, IIndexedOhlcv>
          {
              public override Func<IEnumerable<IOhlcv>, int, IIndexedOhlcv> IndexedObjectConstructor
              {
                  get
                  {
                      return TestMethod;                
                  }
              }
      
              public IIndexedOhlcv TestMethod(IEnumerable<IOhlcv> l, int i)
              {
                  return null;
              }
          }
      
          public interface IOhlcv
          {
      
          }
      
          public interface IIndexedOhlcv
          {
      
          }
      

      现在如果你问为什么我们必须使用 getter 来实现属性。您可以使用不同的语法。您可以按照以下方式进行。

       public class Test1 : Test<IOhlcv, IIndexedOhlcv>
      {
          public override Func<IEnumerable<IOhlcv>, int, IIndexedOhlcv> IndexedObjectConstructor => TestMethod;        
      
          public IIndexedOhlcv TestMethod(IEnumerable<IOhlcv> l, int i)
          {
              return null;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-11-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-03
        • 1970-01-01
        • 2013-07-09
        相关资源
        最近更新 更多