Как неявно привести кастомный IEnumerable в foreach? - PullRequest
2 голосов
/ 05 июня 2019

Я хочу, чтобы var в моем цикле foreach неявно приводил элементы моего кастомного IEnumerable. Он зацикливается на внутреннем Dictionary и в основном является оберткой. Я попробовал общий и неуниверсальный IEnumerable.

Я хочу понять, что необходимо для поддержки неявного приведения в цикле foreach.

public class Bewerbung : IEnumerable<KeyValuePair<string, string>>
{
        protected Dictionary<string, string> internDic = new Dictionary<string, string>();


        public IEnumerator GetEnumerator()
        {
            return internDic.GetEnumerator();
        }

        IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()
        {
            return internDic.GetEnumerator() ;
        }
}
            var bewerbung = new Bewerbung();
            foreach (var testi in bewerbung)
            {

            }

testi всегда является объектом, а не KeyValuePair, как должно быть.

Я знаю, что мог бы использовать явное приведение для практического использования, но я хочу понять, что не так в моем подходе. Другие IEnumerable можно неявно приводить, почему это не работает для моего пользовательского класса?

1 Ответ

7 голосов
/ 05 июня 2019

foreach забавный зверь - он по возможности набирается на утку (имеется в виду: ему действительно не нужен API IEnumerable[<T>], если существует метод public {something} GetEnumerator()), а в вашем случае, publicМетод не является общим.Итак ... поменяйте местами:

IEnumerator IEnumerable.GetEnumerator()
{
    return internDic.GetEnumerator();
}

public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
    return internDic.GetEnumerator();
}

Обратите также внимание на то, что обычным способом является просто прокси явной реализации к public, чтобы избежать ошибок обслуживания, то есть

IEnumerator IEnumerable.GetEnumerator()
    => GetEnumerator();

public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
    => internDic.GetEnumerator();

Youможет даже предоставить пользовательский словарь перечислителя, если вы хотите оптимизировать для этого:

IEnumerator IEnumerable.GetEnumerator()
    => GetEnumerator();

IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()
    => GetEnumerator();

public Dictionary<string, string>.Enumerator GetEnumerator()
    => internDic.GetEnumerator();
...