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

Posted

技术标签:

【中文标题】C# 动态转换超过了不同参数的类型不匹配错误【英文标题】:C# Dynamic casting surpasses the type mismatch error for a different parameter 【发布时间】:2020-08-10 00:34:49 【问题描述】:

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

在下面的sn-p中,第一次调用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
    

【问题讨论】:

***.com/questions/44006718/…? 【参考方案1】:

当您在方法调用中使用 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
    
        

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

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

【讨论】:

【参考方案2】:

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

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

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

【讨论】:

以上是关于C# 动态转换超过了不同参数的类型不匹配错误的主要内容,如果未能解决你的问题,请参考以下文章

选择查询 C# 查询中条件表达式中的数据类型不匹配错误

使用动态导入时玩笑与自定义错误类型不匹配

Ebean - 动态查询 - 准备语句的不匹配参数计数错误

为啥 PhpStorm 会报“参数类型不匹配”错误?

C# Access OleDb 条件表达式中的数据类型不匹配

c#错误不一致的可访问性:参数类型'HRDMSV1.User'比方法更难访问