泛型和类型约束的规则

The*_*Dag 6 .net c# generics

出于好奇,为什么编译器对待一个不受约束的泛型类型与它的typeof(object)有什么不同?

class Bar { }

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

class Foo<T>
{
    void foo(T thing)
    {
        ((Bar)thing).ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

((Bar)(object)thing).ToString();
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ell 4

这里的意义在于object。如果第一个例子不是别的,object它的行为是一样的。基本上,你现在在这里所说的是:

(Bar)thing
Run Code Online (Sandbox Code Playgroud)

是:“将 a 转换T为 a Bar”;在一般情况下,这远不合法。通过添加object你可以做到:

(Bar)(object)thing
Run Code Online (Sandbox Code Playgroud)

这是“将 a 转换Tobject...” - 这始终是合法的,因为它object是所有托管类型的根;并注意这可能涉及一个框 - “...然后将其再次转换objectBar”;它在编译时始终是合法的,并且在运行时涉及类型检查(“unbox-any”)。

例如:假设TDateTime...

DateTime thing = ...
Bar bar = (Bar)(object)thing;
Run Code Online (Sandbox Code Playgroud)

是完全有效的;当然它会在运行时失败,但是:这是您需要记住的场景。