提问人:Stanton 提问时间:8/25/2023 最后编辑:Stanton 更新时间:8/25/2023 访问量:53
当函数将动态对象作为输入参数时,不会检查 C# 类型转换
C# type casting isn't checked when a function takes a dynamic object as input parameter
问:
我有一个接受类型对象的函数。该函数确实可以解析该对象,然后返回有关其解析内容的一些信息。出于某种奇怪的原因,当我获取返回的对象并将其存储到另一个变量中时,该新变量不会在编译时检查对象类型是否匹配。dynamic
在下面的示例中,我尽可能地减少了这个问题。
看这里我调用了两个函数,它们都返回一个类型的值,这些函数之间的唯一区别是其中一个采用类型的输入参数。ReturnDouble()
double
dynamic
在函数中,我只是调用这两个函数并将它们的值存储到类型变量中。我本来以为这两个调用都会给出编译错误,因为您不能隐式地将 a 转换为 ,但奇怪的是,该函数不会抛出错误。DoSomething()
int
double
int
ReturnDouble(dynamic obj)
在此示例中,我使用 's 和 's 来保持简单,但在我更大的代码中,我获取该对象并从中解析大量信息,并传回一个更大的类对象。double
int
dynamic obj
public static double ReturnDouble()
{
return 1.0;
}
public static double ReturnDouble(dynamic obj)
{
// do some stuff with object 'obj'
return 1.0;
}
public static void DoSomething()
{
dynamic obj = new { };
int forSomeReasonThisCompilesWithoutError = ReturnDouble(obj);
int asExpectedThisCompilesWithErrors = ReturnDouble();
}
答:
obj
是一个动态表达式,因为它的类型为 。dynamic
不会对动态表达式进行编译时(静态)绑定。因此,将在运行时完成重载解析。这意味着编译器不知道将返回什么类型。在这种情况下,您可以考虑返回。ReturnDouble
ReturnDouble
ReturnDouble
dynamic
因此,运算符也不是静态绑定的,因此编译器不会检查其两端的表达式是否具有正确的类型。=
相反,动态绑定是在运行时为它们完成的。这意味着您的代码将在运行时引发异常,而不是发出编译器错误。int forSomeReasonThisCompilesWithoutError = ReturnDouble(obj);
从规格。
...但是,如果表达式是动态表达式(即具有 类型),则表示它参与的任何绑定都应基于其运行时类型,而不是编译时具有的类型。因此,此类操作的绑定将推迟到程序运行期间执行该操作的时间。这称为动态绑定。
dynamic
评论
any
strong typed
我不确定将参数定义为 是否实用。相反,我使用 and,当它有用时,我在方法中创建新变量作为动态变量。dynamic
object
public static double ReturnDouble()
{
return 1.0;
}
public static double ReturnDouble(object obj)
{
dynamic dynamicObj = obj;
// do some stuff with object 'dynamicObj'
return 1.0;
}
public static void DoSomething()
{
dynamic obj = new { };
object objAsObject = obj;
int forSomeReasonThisCompilesWithoutError = ReturnDouble(objAsObject);
int asExpectedThisCompilesWithErrors = ReturnDouble();
}
评论
dynamic
object
清扫工的回答解释了发生了什么。解决实际问题的更好方法是使用具有类型约束的泛型,而不是使用 擦除类型信息。dynamic
public static T ReturnNotOnlyDouble<T>(T obj,T other)
where T:IAdditionOperators<T,T,T>
{
var result=obj+other;
return result;
}
此示例有点做作,以显示 .NET 7 如何抽象静态方法(如 IAdditionOperators<> 允许在泛型函数中使用运算符和其他静态方法,这在以前的运行时中是不可能的。我怀疑这就是使用而不是通用方法的原因。dynamic
System.Numerics 现在包含多个运算符接口,包括组合多个运算符的接口,例如 IFloatingPoint,它结合了所有浮点数通用的接口。double 例如实现IFloatingPoint<double>
评论
dynamic obj