C# 动态转换超过了不同参数的类型不匹配错误

C# Dynamic casting surpasses the type mismatch error for a different parameter

当我在将变量传递给函数的泛型类型参数之前将其转换为 dynamic 类型时,下一个参数将绕过类型检查。

在下面的代码片段中,第一次调用 Check 方法是如何逃避编译的?
(dynamic) 转换仅对第一个参数进行(其中 Type1 传递给 Interface1)。但是 Type1 传递给 Interface2 的第二个参数没有编译失败。

interface Interface1 { }
interface Interface2 { }

class Type1 : Interface1 { }
class Type2 : Interface2 { }

class Program
{
    public static void Check<T1, T2>(T1 obj1, T2 obj2) where T1 : Interface1 where T2 : Interface2
    {
    }

    static void Main(string[] args)
    {
        Check((dynamic)new Type1(), new Type1()); //passes compliation and fails in runtime

        Check(new Type1(), new Type1()); //fails in compilation
    }
}

当您使用 any 动态值作为方法调用中的参数时,该方法是动态绑定的。如果您完全使用泛型类型推断(无论动态值是否涉及其中),则不会验证泛型类型约束。

这是您所看到的稍微简单一点的版本:

using System;

class Test
{
    static void Main()
    {
        dynamic d = 1;
        // Compiles
        M(d, 0);

        // Doesn't compile - explicit type argument
        M<int>(d, 0);
    }

    static void M<T>(object ignored, T value) where T : class
    {
    }    
}

编译器会做一些检查,但它在检查的内容上相对保守。从根本上说,如果您正在深入研究动态绑定领域,您应该非常小心,并预料到事情可能不会像您认为的那样进行类型检查。

(如果我没记错的话,规范对于动态绑定操作执行了多少检查相当松散,因此您可能会遇到这样一种情况,即它可以使用某些编译器进行编译,但不能使用其他编译器进行编译。)

使用dynamic 导致泛型类型检查被推迟到运行时。一旦任何参数为 dynamic,那么整个事情就会被延迟,因此在第一个语句中,单个 dynamic 会导致延迟。

没有它,在第二个语句中,检查是在编译时完成的,因此会因编译器错误而失败。

在这两种情况下调用都是无效的:obj2 不能属于 Type1,因为 Type1 没有实现 Interface2。只是什么时候抓到错误的问题。