C # Абстрактное назначение Func (делегаты) - PullRequest
0 голосов
/ 28 января 2019

У меня есть следующая абстрактная функция.

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

Мой вопрос связан со способом реализации.1-й: я создаю метод с той же сигнатурой

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

, присваиваю его функции.

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

Однако, это показывает ошибку

Ошибка CS0106 Модификатор 'override' недопустим для этого элемента

Я знаю, что это можетбыть решенным с помощью лямбды следующим образом:

 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;"не работает?

Ответы [ 4 ]

0 голосов
/ 28 января 2019

Это полный рабочий пример.

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;
    }
}
0 голосов
/ 28 января 2019

IndexedObjectConstructor является свойством только для получения, которое возвращает Func<IEnumerable<TInput>, int, TIndexed>.При попытке переопределения вы определяете поле IndexedObjectConstructor, которое пытаетесь инициализировать с помощью Test.

Поля не могут быть переопределены (и даже если они могут быть, это свойство в базе).класс, а не поле) и Test, сам по себе, в любом случае не является средством получения свойства.

Когда вы реализуете его «с лямбда-выражением», вы используете относительно новое встроенное свойство Синтаксис объявления .

0 голосов
/ 28 января 2019

Это потому, что переопределенная вещь - это свойство, которое означает, что вы должны объявить аксессор get при переопределении, что не выполняется при выполнении

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

, это также объясняет, почему работает следующее

public override Func<IEnumerable<IOhlcv>, int, IIndexedOhlcv> IndexedObjectConstructor => Test;
0 голосов
/ 28 января 2019

Вы не можете просто присвоить метод свойству.Вам необходимо полностью реализовать 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;
...