不同固件之间的协方差会导致代码中断吗?

发布于 2025-01-07 06:47:24 字数 542 浏览 2 评论 0原文

我在 NDC 2010 上看到 Jon Skeet 的演讲,

他提到了一些有趣的事情:

public Class Base
{
 public void Foo(IEnumerable<string> strings){}
}

public Class Child:Base
{
 publc void Foo(IEnumerable<object> objects) {}
}

Main :

List<string> lst = new List<string>();
lst.Add("aaa");
Child c = new Child();
c.Foo(lst);

使用 C# 3 它将调用:Base.Foo

使用 C# 4 它将调用:Child.Foo

我知道这是因为协方差

问题:

这不是一个破坏代码的改变吗? 是否有任何解决方法可以让此代码像版本 3 上一样继续工作?

I saw Jon Skeet's lecture at the NDC 2010

He mentioned something interesting :

public Class Base
{
 public void Foo(IEnumerable<string> strings){}
}

public Class Child:Base
{
 publc void Foo(IEnumerable<object> objects) {}
}

Main :

List<string> lst = new List<string>();
lst.Add("aaa");
Child c = new Child();
c.Foo(lst);

With C# 3 it will call : Base.Foo

With C# 4 it will call : Child.Foo

I know it's because covariance

Question :

Isn't it a bit code breaking change ?
Is there any workaround so this code will continue work as it was on ver 3?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

笑咖 2025-01-14 06:47:24

是的,这是一个突破性的改变。每当您将以前无效的转换变为合法时,这都是一个重大更改。

不幸的是,在不进行任何重大更改的情况下,很难向该语言添加功能。如果您确实想要查找,还有更多有关 C# 4 中的事件的信息。当然,这些不太可能影响大多数开发人员。

C# 1 和 C# 2 之间也存在类似的重大更改,其中所使用的实现在该代码的不同版本之间会发生变化:

using System;

public delegate void StringAction(string x);

public class Base
{
    public void Foo(string x)
    {
        Console.WriteLine("Base");
    }
}

public class Child : Base
{
    public void Foo(object x)
    {
        Console.WriteLine("Child");
    }
}

public class Test
{
    static void Main()
    {
        Child c = new Child();
        StringAction action = new StringAction(c.Foo);
        action("x");
    }
}

在这种情况下,编译器实际上会发出警告:

Test.cs(26,31): warning CS1707: Delegate 'StringAction' bound to
        'Child.Foo(object)' instead of 'Base.Foo(string)' because of new
        language rules

Yes, it's a breaking change. Any time you make a prevously-invalid conversion legal, it's a breaking change.

Unfortunately, it's very hard to add features to the language without making any breaking changes. There are a few more around events in C# 4 if you really want to look for them. It's unlikely that these will affect most developers, of course.

There were similar breaking changes between C# 1 and C# 2, where the implementation used would have changed between different versions for this code:

using System;

public delegate void StringAction(string x);

public class Base
{
    public void Foo(string x)
    {
        Console.WriteLine("Base");
    }
}

public class Child : Base
{
    public void Foo(object x)
    {
        Console.WriteLine("Child");
    }
}

public class Test
{
    static void Main()
    {
        Child c = new Child();
        StringAction action = new StringAction(c.Foo);
        action("x");
    }
}

In this case the compiler actually gives a warning:

Test.cs(26,31): warning CS1707: Delegate 'StringAction' bound to
        'Child.Foo(object)' instead of 'Base.Foo(string)' because of new
        language rules
最丧也最甜 2025-01-14 06:47:24

乔恩当然是对的;这是一个突破性的改变。查看重大更改的更简单方法是:

object x = new List<string>();
if (x is IEnumerable<object>) 
    Console.WriteLine(4);
else
    Console.WriteLine(3);

在 C# 3 中打印 3;在 C# 4 中,它打印 4。

当您更改类型系统时,您会更改重载解析的结果;事情就是这样。该功能的好处超过了可能出现的中断带来的痛苦。

有解决方法吗?是的。首先不要调用 Child.Foo:

Base c = new Child();
c.Foo(list);

Jon is of course right; it is a breaking change. An even easier way to see that breaking change is:

object x = new List<string>();
if (x is IEnumerable<object>) 
    Console.WriteLine(4);
else
    Console.WriteLine(3);

In C# 3 that prints 3; in C# 4 it prints 4.

When you change the type system, you change the results of overload resolution; that's just how it goes. The benefit of the feature outweighs the pain of the possible breaks.

Is there a workaround? Yes. Don't call Child.Foo in the first place:

Base c = new Child();
c.Foo(list);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文