加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 泛型和类型约束的规则

发布时间:2020-12-15 04:22:58 所属栏目:百科 来源:网络整理
导读:出于好奇,为什么编译器对待一个不受约束的泛型类型与它的typeof(object)有什么不同? class Bar { }class Foo{ void foo(object thing) { ((Bar)thing).ToString(); }}class FooT{ void foo(T thing) { ((Bar)thing).ToString(); }} 在上面,将“T thing”转
出于好奇,为什么编译器对待一个不受约束的泛型类型与它的typeof(object)有什么不同?
class Bar { }

class Foo
{
    void foo(object thing)
    {
        ((Bar)thing).ToString();
    }
}

class Foo<T>
{
    void foo(T thing)
    {
        ((Bar)thing).ToString();
    }
}

在上面,将“T thing”转换为Bar会导致编译器错误.然而,将“对象事物”转换为Bar是编译器允许我做的事情,当然我自担风险.

我没看到的是为什么.在.net对象中,毕竟是catch-all,运行时类型可以是盒装值或任何类型的对象.所以我没有看到编译器区分这两种情况的逻辑原因.我能做的最好就是“程序员希望编译器使用泛型类型进行类型检查,但不能使用对象”. :)这就是它的全部吗?

顺便说一句,我知道我仍然可以通过简单的写作在Foo案例中完成我的演员阵容

((Bar)(object)thing).ToString();

我只是想了解为什么编译器会这样做……

解决方法

这里的意义是对象.如果第一个例子是除了object之外的任何东西,那么它的行为会相同.基本上,你现在在说什么:
(Bar)thing

是:“将T转换为条形码”;在一般情况下,这远远不合法.通过添加对象,您可以:

(Bar)(object)thing

这是“将T转换为对象……” – 这总是合法的,因为对象是所有托管类型的根;并注意这可能会打开一个框 – “……然后将对象作为一个条形图” – 再次;它在编译时总是合法的,并且在运行时涉及类型检查(“unbox-any”).

例如:假设T是DateTime …

DateTime thing = ...
Bar bar = (Bar)(object)thing;

完全有效;确定它会在运行时失败,但是:这是你需要记住的场景.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读