после перехода с .NET 3.5 на 4.0 у меня возникла странная проблема с функцией, приводящей к переполнению стека на 4.0 при идеальной работе на платформе 3.5.Я воспроизвел проблему со следующим кодом:
public interface IPerson
{
string Name { get; }
}
public class Person : IPerson
{
public Person() { }
public Person(IPerson source)
{
this.Name = source.Name;
}
public string Name { get; set; }
}
public class PersonList : List<Person>
{
public void AddRange(IEnumerable<IPerson> source)
{
this.AddRange(source.Select(p => new Person(p)));
}
}
Вызов ошибки:
IPerson otto = new Person { Name = "Otto" };
IPerson fritz = new Person { Name = "Fritz" };
PersonList list = new PersonList();
IEnumerable<IPerson> persons = new[] { otto, fritz };
list.AddRange(persons); //works on 3.5, stack overflow on 4.0
Посмотрите на метод AddRange(IEnumerable<IPerson> source)
PersonList
.В 3.5 вызывается метод AddRange(IEnumerable<Person> source)
, полученный из List<Person>
.В 4.0 метод AddRange(IEnumerable<IPerson> source)
вызывается (рекурсия) из-за ковариации, несмотря на то, что существует функция лучшего соответствия с параметром (IEnumerable<Person>I
), точно совпадающим с входным параметром.
Это новое поведениезадумано и задокументировано?