gpt4 book ai didi

c#-4.0 - .NET 4.0 中方法重载和协变的重大变化

转载 作者:行者123 更新时间:2023-12-02 20:28:06 24 4
gpt4 key购买 nike

从 .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 ) 与输入参数完全匹配的更好匹配函数,但由于协方差而调用(递归)方法。

这种新行为是有意为之并记录在案的吗?

最佳答案

这是正确的 C# 行为,因为在 C# if any method on a more-derived class is an applicable candidate, it is automatically better than any method on a less-derived class, even if the less-derived method has a better signature match. 中所以 C# 4 做了 AddRange(IEnumerable<IPerson> source)一个合适的候选人,然后是更好的签名 AddRange(IEnumerable<Person> source)位于基类中,因此不会被选中。

但由于规则的原因,在您的情况下它很容易修复。

public class PersonList  : List<Person>
{
public void AddRange(IEnumerable<IPerson> source)
{
base.AddRange(source.Select(p => new Person(p)));
}
}

关于c#-4.0 - .NET 4.0 中方法重载和协变的重大变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5550546/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com