доступ к базовому классу C # в итераторе вызывает предупреждение ReSharper - PullRequest
2 голосов
/ 29 июня 2010

У меня есть два класса, GenericList и SpecificList, где SpecificList наследуется от GenericList.GenericList реализует IEnumerable<GenericItem> и SpecificList реализует IEnumerable<SpecificItem>.SpecificItem наследуется от GenericItem.Я должен реализовать GetEnumerator в GenericList и SpecificList, так как они реализуют IEnumerable<T>GenericList это достаточно просто, я просто возвращаю перечислитель для базового List<T>:

public IEnumerator<GenericItem> GetEnumerator()
{
    return genericItemsList.GetEnumerator();
}

Однако в SpecificList это кажется сложнее.Кажется рискованным бросать IEnumerator<GenericItem> на IEnumerator<SpecificItem>, и я не знаю, сработает ли это вообще.Вместо этого я сделал следующее:

public new IEnumerator<SpecificItem> GetEnumerator()
{
    IEnumerator<GenericItem> enumerator = base.GetEnumerator();
    while (enumerator.MoveNext())
    {
        yield return (SpecificItem)enumerator.Current;
    }
}

Это прекрасно компилируется, и простой модульный тест MSTest, вызывающий SpecificList.GetEnumerator(), похоже, показывает, что он работает.Однако ReSharper выделяет base в вышеупомянутом методе со следующим предупреждением:

Доступ к GenericList.GetEnumerator через ключевое слово «base» из анонимного метода, лямбда-выражения, запроса или итератора приводит к непроверяемому коду

Это то, о чем мне следует беспокоиться?Должен ли я сделать что-то по-другому?

Редактировать: Я использую ReSharper 5.1 Full Edition Pre-Release Build 5.1.1715.35.

Кроме того, я должен отдохнуть отвыполнение модульных тестов MSTest: я просто нажал Ctrl + R , Ctrl + T в Chrome, чтобы перезагрузить страницу ...

Ответы [ 2 ]

6 голосов
/ 29 июня 2010

R # правильно, что доступ к ключевому слову base внутри итератора / лямбды в версии 3.0 компилятора C # может привести к непроверяемому коду. Когда это происходит или нет, это немного сложно, и я не буду пытаться осветить это здесь.

Самый простой способ обойти это - заключить вызов в base.GetEnumerator в другой нестатический приватный метод и сослаться на него из вашего итератора.

private IEnumerator<GenericItem> GetBaseEnumerator() {
  return base.GetEnumerator();
}

public new IEnumerator<SpecificItem> GetEnumerator()
{
    IEnumerator<GenericItem> enumerator = GetBaseEnumerator();
    while (enumerator.MoveNext())
    {
        yield return (SpecificItem)enumerator.Current;
    }
}

Я вполне уверен, что эта ошибка была исправлена ​​в версии 4.0 компилятора C #.

0 голосов
/ 29 июня 2010

Кажется рискованным приводить IEnumerator<GenericItem> к IEnumerator<SpecificItem>, и я не знаю, сработает ли это.

Конечно, будет.

return base.Cast<SpecificItem>().GetEnumerator();

Не более или менее рискованно, чем ваша текущая реализация.На самом деле, я уверен, что это более-менее тот же код под капотом.

...