具有动态函数参数的 C# 编译器类型推断
C# compiler type inference with dynamic function parameters
当我调用函数并将其中一个参数替换为动态时,编译器将函数结果推断为动态。我不明白为什么会这样。
示例:a 的推断类型是动态的,因此此代码可以编译,但当然会在运行时因 RuntimeBinderException 而失败:
dynamic b = "";
var a = MethodWithoutOverloads("", b);
a.DoesNotExist();
...
public string MethodWithoutOverloads(string a, string b) { ... }
有人知道为什么推断出的类型不是函数的return类型吗?
编辑:编辑以明确这种情况发生在没有重载的方法中
因为编译器不知道哪个方法将在运行时间被调用。
例如,您可能有以下两种方法:
int MyMethod(int a)
{
return 5;
}
double MyMethod(string a)
{
return 6.0;
}
然后你写下下面的代码:
dynamic myThing = 5;
var myResult = MyMethod(myThing);
考虑到我们已经明确地说 myThing
是 动态的 ,并且它的类型将在 运行 时确定,我们不知道哪个方法将被调用(如果有的话)。因此,我们也不知道 return 类型。
你是对的,编译器可以推断出所有String.Format
重载return一个string
并因此推断出a
必须是字符串,无论 b
实际是什么。
事实是编译器不会那样做。它解决了一般情况,这很好,并且由于具有不同 return 类型的重载在 C# 中有效,它只是将 return 类型分配为动态类型并让运行时计算出来。
回答您的具体问题,
public string MethodWithoutOverloads(string a, string b) { ... }
dynamic a = "";
var result = MethodWithoutOverloads(a, a); // result is dynamic.
让我们想象一下,编译器决定 result
是 string
,然后你将你的图书馆发布到狂野的西部。然后,稍后,您决定添加具有以下签名的重载:
public int MethodWithoutOverloads(int a, int b) { ... }
现在,result
的类型应该是什么?而且,依赖于 result
的现有代码会发生什么情况被强类型化为 string
?
string result = MethodWithoutOverloads(someDynamicVariable, someOtherDynamicVariable);
语义完全改变;在消费者拥有安全的强类型变量之前,现在他突然拥有一个可能在运行时爆炸的潜在不安全隐式转换。
当我调用函数并将其中一个参数替换为动态时,编译器将函数结果推断为动态。我不明白为什么会这样。
示例:a 的推断类型是动态的,因此此代码可以编译,但当然会在运行时因 RuntimeBinderException 而失败:
dynamic b = "";
var a = MethodWithoutOverloads("", b);
a.DoesNotExist();
...
public string MethodWithoutOverloads(string a, string b) { ... }
有人知道为什么推断出的类型不是函数的return类型吗?
编辑:编辑以明确这种情况发生在没有重载的方法中
因为编译器不知道哪个方法将在运行时间被调用。
例如,您可能有以下两种方法:
int MyMethod(int a)
{
return 5;
}
double MyMethod(string a)
{
return 6.0;
}
然后你写下下面的代码:
dynamic myThing = 5;
var myResult = MyMethod(myThing);
考虑到我们已经明确地说 myThing
是 动态的 ,并且它的类型将在 运行 时确定,我们不知道哪个方法将被调用(如果有的话)。因此,我们也不知道 return 类型。
你是对的,编译器可以推断出所有String.Format
重载return一个string
并因此推断出a
必须是字符串,无论 b
实际是什么。
事实是编译器不会那样做。它解决了一般情况,这很好,并且由于具有不同 return 类型的重载在 C# 中有效,它只是将 return 类型分配为动态类型并让运行时计算出来。
回答您的具体问题,
public string MethodWithoutOverloads(string a, string b) { ... }
dynamic a = "";
var result = MethodWithoutOverloads(a, a); // result is dynamic.
让我们想象一下,编译器决定 result
是 string
,然后你将你的图书馆发布到狂野的西部。然后,稍后,您决定添加具有以下签名的重载:
public int MethodWithoutOverloads(int a, int b) { ... }
现在,result
的类型应该是什么?而且,依赖于 result
的现有代码会发生什么情况被强类型化为 string
?
string result = MethodWithoutOverloads(someDynamicVariable, someOtherDynamicVariable);
语义完全改变;在消费者拥有安全的强类型变量之前,现在他突然拥有一个可能在运行时爆炸的潜在不安全隐式转换。