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
。只是什么时候抓到错误的问题。
当我在将变量传递给函数的泛型类型参数之前将其转换为 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
。只是什么时候抓到错误的问题。