c# - sealed 关键字会影响编译器对强制转换的看法

标签 c# visual-studio-2010 compiler-errors

我有一种情况想要解释编译器的行为。给出一些代码:

interface IFoo<T>
{
    T Get();
}

class FooGetter : IFoo<int>
{
    public int Get()
    {
        return 42;
    }
}

以下编译并运行:

static class FooGetterGetter
{
    public static IFoo<T> Get<T>()
    {
        return (IFoo<T>)new FooGetter();
    }
}

如果我们更改 Foo 的签名类并添加 sealed关键词:

sealed class FooGetter : IFoo<int> // etc

然后我在以下行中收到编译器错误:

 return (IFoo<T>)new FooGetter();

属于:

Cannot convert type 'MyNamespace.FooGetter' to 'MyNamespace.IFoo<T>'

有人可以解释这里发生的关于 sealed 的事情吗?关键词?这是针对 Visual Studio 2010 中的 .NET 4 项目的 C# 4。

更新:有趣的是,当我想知道为什么以下代码在 sealed 时修复它时,我偶然发现了这部分行为。被应用:

return (IFoo<T>)(IFoo<int>)new FooGetter();

更新: 只是为了澄清,当类型为 T 时一切正常requested 与 T 的类型相同由具体类型使用。如果类型不同,则转换在运行时会失败,例如:

Unable to cast object of type 'MyNamespace.StringFoo' to type 'MyNamespace.IFoo`1[System.Int32]'

在上面的例子中,StringFoo : IFoo<string>来电者要求获得 int .

最佳答案

因为 FooGetterIFoo<int> 的显式实现而不是实现 IFoo<T>一般地。由于它是密封的,编译器知道无法将其转换为通用的 IFoo<T>。如果Tint 以外的任何东西.如果它没有被密封,编译器将允许它编译并在运行时抛出异常如果 T不是 int .

如果您尝试将它与 int 以外的任何东西一起使用(例如 FooGetterGetter.Get<double>(); )你得到一个异常(exception):

Unable to cast object of type 'MyNamespace.FooGetter' to type 'MyNamespace.IFoo`1[System.Double]'.

我不确定为什么编译器不会为非密封版本生成错误。你的子类怎么会FooGetter这样 new FooGetter()给你任何实现 IFoo<{something_other_than_int}> 的东西?

更新:

根据 Dan BryantAndras Zoltan有一些方法可以从构造函数返回派生类(或者更准确地说,编译器可以通过分析属性返回不同的类型)。所以从技术上讲,如果类不是密封的,这是可行的。

关于c# - sealed 关键字会影响编译器对强制转换的看法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8912542/

相关文章:

c++ - char* 与 const char* (再次!!!)

c# - 使用 Razor Pages 在 ASP.NET Core MVC 中使用 Handler 设置 Kendo UI Grid DataSource Read 属性

c# - 在 Iframe 中打开 pdf 传递字节数据

c# - 如何获取元素的CSS类名称

visual-studio - Visual Studio 2010安装

c# - 错误 "Cannot perform Like Operation on ' System.Int3 2' and ' System.String'”设置DataGridView数据源

python-3.x - 名称错误: name 'get_ipython' is not defined

c# - 如何旋转图片框中的图片

c++ - tbb::concurrent_queue 容器中的 std::deque 是否等效?

java - 找不到符号获取文本和settext