Блоки итераторов и наследование

Следующий рекурсивный алгоритм выбирает все комбинации k-элементов из упорядоченного множества:

  • выбирает первый элемент i вашей комбинации
  • i ] с каждой из комбинаций элементов k-1, выбранных рекурсивно из набора элементов, большего, чем i.

Итерацию выше для каждого i в наборе.

Очень важно, чтобы остальные элементы были больше, чем i, чтобы избежать повторения. Этот путь [3,5] будет выбран только один раз, поскольку [3] в сочетании с [5] вместо двух (условие исключает [5] + [3]). Без этого условия вы получаете варианты вместо комбинаций.

16
задан Dave Van den Eynde 12 March 2010 в 13:01
поделиться

4 ответа

Как насчет:

public class Derived : Base
{
    public override IEnumerable<string> GetListOfStuff()
    {
        return base.GetListOfStuff().Concat(GetMoreStuff());        
    }
    private IEnumerable<string> GetMoreStuff()
    {
        yield return "Fourth";
        yield return "Fifth";
    }
}
12
ответ дан 30 November 2019 в 21:10
поделиться

Между прочим, причина этого странного поведения заключается в том, что команда безопасности CLR изменила верификатор непосредственно перед отправкой v2, так что стало невозможно проверить не виртуальный вызов виртуального метода одного класса из метода в другом класс.

Для дальнейшего объяснения этой проблемы см. Мою статью на эту тему несколько лет назад.

http://blogs.msdn.com/ericlippert/archive/2005/11/14/why-are-base-class-calls-from-anonymous-delegates-nonverifiable.aspx

Это сейчас устарело; мы исправили компилятор, чтобы он теперь генерировал для вас помощник.

9
ответ дан Eric Lippert 12 March 2010 в 13:01
поделиться

Похоже, что одним из решений было просто следовать тому, что говорится в "руководстве": сделать вспомогательную функцию.

Так что на данный момент я решил эту проблему следующим образом:

public class Derived : Base
{
    private IEnumerable<string> GetBaseStuff()
    {
        return base.GetListOfStuff();
    }

    public override IEnumerable<string> GetListOfStuff()
    {
        foreach (string s in GetBaseStuff())
        {
            yield return s;
        }

        yield return "Fourth";
        yield return "Fifth";
    }
}

Но мне интересно узнать и о других решениях, если они существуют.

4
ответ дан 30 November 2019 в 21:10
поделиться

Это происходит потому, что итератор превращается в частный класс, а доступ к методам суперкласса из внутреннего класса не проверяется (поскольку он должен принудительно указывать указатель 'this' на что-то, кроме себя).

Попробуйте создать новый приватный метод в Derived:

private IEnumerable<string> GetBaseListOfStuff()
{        
    return base.GetListOfStuff();
}

и вызвать его вместо base.GetListOfStuff()

3
ответ дан 30 November 2019 в 21:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: