IEnumerable. GetEnumerator () и IEnumerable <T>.GetEnumerator ()

В платформе .NET существует дженерик IEnumerable<T> интерфейс, который наследовался не - универсальный IEnumerable, и у них обоих есть a GetEnumerator() метод. Единственный differents между этими двумя GetEnumerator() тип возврата. Теперь у меня есть подобный дизайн, но когда я компилирую код, сказанный компилятор:

MyInterface<T>.GetItem()'скрывает наследованного участника'MyInterface.GetItem()'. Используйте новое ключевое слово, если сокрытие было предназначено.

MyInterface<T>.GetItem() возвращает конкретный тип T, в то время как MyInterface.GetItem() система типов возвратов. Объект.

Таким образом, я думаю, компилируют ли парни команды BCL платформу .NET, они получат то же предупреждение.

Я думаю, имея предупреждения компилятора, не хорошо, что Вы думаете? И как я могу решить эту проблему? Я подразумеваю, что хочу получить конкретный тип T при вызове MyInterface<T>.GetItem() не только экземпляр системы типов. Объект.

Заранее спасибо! :-)

Дополнение: я говорю что интерфейсы theirselves: IMyInterface наследовался IMyInterface, и у них обоих есть GetItem () метод (IMyInterface. GetItem () возвращает тип T, в то время как IMyInterface. GetItem () возвращает систему типов. Объект). Проблема состоит в том, что, если наш код только имеет эти два интерфейса, то есть, никакие полученные реальные классы, мы встретимся с предупреждением компилятора после компиляции исходный код.

5
задан Ruben Bartelink 11 January 2011 в 09:50
поделиться

2 ответа

Они не делают этого, потому что компилируют одну версию как явную реализацию метода интерфейса. Это выглядит так:

public class SomeClassThatIsIEnumerable<T> : IEnumerable<T>
{
    public IEnumerator<T> GetEnumerator()
    {
       // return enumerator.
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return ((IEnumerable<T>)this).GetEnumerator();
    }
}

Что делает эта конструкция, так это заставляет первый метод GetEnumerator стать методом по умолчанию, в то время как другой метод GetEnumerator доступен только если вызывающая сторона сначала приведет SomeClassThatIsIEnumerable к типу IEnumerator, так что это позволяет избежать проблемы.

Edit: исходя из дополнения выше, вы захотите использовать новое ключевое слово:

public interface IMyInterface
{
   object GetObject();
}

public interface IMyInterface<T> : IMyInterface
{
   new T GetObject();
}

// implementation:

public class MyClass : IMyInterface<string>
{
    public string GetObject() 
    {
        return "howdy!";
    }

    object IMyInterface.GetObject()
    {
        return GetObject();
    }
}
10
ответ дан 18 December 2019 в 14:44
поделиться

Разница в том, что IEnumerable и IEnumerable - это интерфейсы. В конкретном типе, реализующем оба интерфейса, по крайней мере один из них должен быть реализован явно.

В наследовании конкретного типа вы должны использовать ключевое слово new, чтобы указать, что вы хотите перезаписать метод из базового типа. При применении нового ключевого слова метод не наследуется. Это означает, что myTypeInstance.Method вызовет метод, определенный в MyType , а ((MyBaseType) myTypeInstance) .Method вызовет метод, определенный для базового типа. .

public interface Interface1 {
    object GetItem();
}

public interface Interface2<T> : Interface1 {
    T GetItem();
}

public class MyBaseType : Interface1 {
    public object GetItem() {
        // implements Interface1.GetType()
        return null;
    }
}

public class MyType<T> : Interface1, Interface2<T> {
    public new T GetItem() {
        // Implements Interface2<T>.GetItem()
        return default(T);
    }

    object Interface1.GetItem() {
        // implements Interface1.GetItem()
        return this.GetItem();   // calls GetItem on MyType
    }
}

var myType = new MyType();
var myTypeResult = myType.GetItem(); // calls GetItem on MyType
var myBaseTypeResult = new ((MyBaseType) myType).GetItem(); // calls GetItem on MyBaseType
3
ответ дан 18 December 2019 в 14:44
поделиться
Другие вопросы по тегам:

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