Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/266.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将动态对象传递给C#方法会更改返回类型_C#_Generics_Dynamic - Fatal编程技术网

将动态对象传递给C#方法会更改返回类型

将动态对象传递给C#方法会更改返回类型,c#,generics,dynamic,C#,Generics,Dynamic,我创建了一个静态方法,并希望创建一个静态方法,该方法可以创建具有预定义属性的新实例(存储在字典中) 公共类CustomDynamic:DynamicObject { 受保护的词典; 公共静态T Create(Dictionary Dictionary),其中T:CustomDynamic,new() { 返回新的T { 字典 }; } } 用法: dynamic d = new Dictionary<string, object>(); var realPlayer = Cust

我创建了一个静态方法,并希望创建一个静态方法,该方法可以创建具有预定义属性的新实例(存储在
字典中)

公共类CustomDynamic:DynamicObject
{
受保护的词典;
公共静态T Create(Dictionary Dictionary),其中T:CustomDynamic,new()
{
返回新的T
{
字典
};
}
}
用法:

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
dynamic d=newdictionary();
var realPlayer=CustomDynamic.Create(d作为字典);
var dynaPlayer=CustomDynamic.Create(d);
realPlayer//根据VS2013的播放器类型
dynaPlayer//根据VS2013的动态类型

既然只有一个方法签名,为什么传入一个动态对象会返回一个动态对象?或者实际上只是VisualStudio2013变得混乱了

这就是动态的工作原理。从

如果方法调用中的一个或多个参数的类型为dynamic,或者方法调用的接收方的类型为dynamic,则重载解析将在运行时而不是在编译时发生


您可能认为您的方法没有任何额外的重载,但您可能有。编译器不会在编译时执行该检查,所以这就是为什么您将
dynaPlayer
的类型视为动态的,而不是
Player

动态的工作方式。从

如果方法调用中的一个或多个参数的类型为dynamic,或者方法调用的接收方的类型为dynamic,则重载解析将在运行时而不是在编译时发生

您可能认为您的方法没有任何额外的重载,但您可能有。编译器不会在编译时执行该检查,所以这就是为什么您将
dynaPlayer
的类型视为动态的,而不是
Player

这是因为几乎所有涉及动态值的操作都会在执行时动态解析。对于编译时只有一个方法的情况没有例外;那样的话,语言就更简单了。(对于某些调用,编译器会在编译时执行足够的解析,以确保至少有一个方法具有适当数量的参数-这在第7.5.4节的C#5规范中有规定,但不会影响有效的返回类型。)

根据C#5规范第7.6.5节:

如果至少满足以下条件之一,则调用表达式将被动态绑定:

  • 主表达式具有编译时类型
    dynamic
  • 可选参数列表中至少有一个参数具有编译时类型
    dynamic
    ,并且主表达式没有委托类型
在这种情况下,编译器将调用表达式分类为
dynamic
类型的值。[……]

有一些涉及动态值的操作仍然具有非动态的总体类型。例如:

  • d是Foo
    总是
    bool
  • d作为Foo
    始终是
    Foo
  • newfoo(d)
    始终是
    Foo
    ,即使要使用的确切构造函数是在执行时确定的
但是任何方法调用都被视为返回类型为
dynamic

,这是因为几乎所有涉及动态值的操作都是在执行时动态解析的。对于编译时只有一个方法的情况没有例外;那样的话,语言就更简单了。(对于某些调用,编译器会在编译时执行足够的解析,以确保至少有一个方法具有适当数量的参数-这在第7.5.4节的C#5规范中有规定,但不会影响有效的返回类型。)

根据C#5规范第7.6.5节:

如果至少满足以下条件之一,则调用表达式将被动态绑定:

  • 主表达式具有编译时类型
    dynamic
  • 可选参数列表中至少有一个参数具有编译时类型
    dynamic
    ,并且主表达式没有委托类型
在这种情况下,编译器将调用表达式分类为
dynamic
类型的值。[……]

有一些涉及动态值的操作仍然具有非动态的总体类型。例如:

  • d是Foo
    总是
    bool
  • d作为Foo
    始终是
    Foo
  • newfoo(d)
    始终是
    Foo
    ,即使要使用的确切构造函数是在执行时确定的
但是,任何方法调用都被视为具有
动态
的返回类型

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