将动态对象传递给C#方法会更改返回类型 [英] Passing dynamic object to C# method changes return type
问题描述
我创建了一个继承 DynamicObject
并且想创建一个静态方法,该方法可以使用预定义属性创建新实例(存储在 Dictionary
中) 。
public class CustomDynamic:DynamicObject
{
保护字典< string,object> InnerDictionary;
$ b $ public static T创建< T>(Dictionary< string,object> dictionary)其中T:CustomDynamic,new()
{
return new T
{
InnerDictionary = dictionary
};
$ / code $ / pre
用法:
dynamic d = new Dictionary< string,object>();
var realPlayer = CustomDynamic.Create< Player>(d as Dictionary< string,object>);
var dynaPlayer = CustomDynamic.Create< Player>(d);
realPlayer //根据VS2013的玩家类型
dynaPlayer //根据VS2013的动态类型
由于只有一个方法签名,为什么传入一个动态返回一个动态对象呢?或者实际上只是Visual Studio 2013变得困惑?
解决方案这是因为涉及动态值的几乎任何操作都是在执行时动态解析的。对于实际上编译时只有一种方法的情况,并没有例外;这种方式的语言更简单。 (对于某些调用,编译器不会在编译时执行足够的分辨率,以确保至少有一个方法具有适当数量的参数 - 这在7.5节中的C#5规范中指定。 4),但不会影响有效的返回类型。)
从C#5规范的第7.6.5节:
如果以下至少一项成立,则 invocation-expression 将被动态绑定:
- primary-expression 具有编译时类型
dynamic
。
- At可选的参数列表中至少有一个参数具有编译时类型
动态
和主表达式没有一个委托类型。
在这种情况下,编译器将 invocation-expression 分类为动态
。 [b]
涉及动态值的少数操作仍然具有非动态整体类型。例如:
-
d是Foo
总是 bool
-
d作为Foo
总是 Foo
-
新的Foo(d)
总是 Foo
,即使确切的构造函数使用是在执行时确定的
但任何方法调用都被视为返回类型为 dynamic
。
I created a class that inherits DynamicObject
and want to create a static method that can create new instances with pre-determined properties (stored in the Dictionary
).
public class CustomDynamic : DynamicObject
{
protected Dictionary<string, object> InnerDictionary;
public static T Create<T>(Dictionary<string, object> dictionary) where T : CustomDynamic , new()
{
return new T
{
InnerDictionary = dictionary
};
}
}
Usage:
dynamic d = new Dictionary<string, object>();
var realPlayer = CustomDynamic.Create<Player>(d as Dictionary<string, object>);
var dynaPlayer = CustomDynamic.Create<Player>(d);
realPlayer // Player type according to VS2013
dynaPlayer // dynamic type according to VS2013
Since there is only one method signature, why does passing in a dynamic return a dynamic object? Or is actually just Visual Studio 2013 getting confused?
解决方案 This is because almost any operation involving a dynamic value is resolved dynamically at execution time. There are no exceptions made for cases where actually there's only one method present at compile-time; the language is simpler that way. (For certain calls, the compiler does perform enough resolution at compile-time to ensure that there is at least one method with a suitable number of parameters - this is specified in the C# 5 spec in section 7.5.4, but that doesn't affect the effective return type.)
From the C# 5 spec, section 7.6.5:
An invocation-expression is dynamically bound if at least one of the following holds:
- The primary-expression has compile-time type
dynamic
.
- At least one argument of the optional argument-list has compile-time type
dynamic
and the primary-expression does not have a delegate type.
In this case the compiler classifies the invocation-expression as a value of type dynamic
. [...]
There are a few operations involving dynamic values which still have a non-dynamic overall type. For example:
d is Foo
is always bool
d as Foo
is always Foo
new Foo(d)
is always Foo
even though the exact constructor to use is determined at execution time
But any method call is treated as having a return type of dynamic
.
这篇关于将动态对象传递给C#方法会更改返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!