简体   繁体   English

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

[英]Passing dynamic object to C# method changes return type

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 ).我创建了一个继承DynamicObject类,并希望创建一个静态方法,该方法可以创建具有预先确定的属性(存储在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?或者实际上只是 Visual Studio 2013 感到困惑?

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.) (对于某些调用,编译器确实在编译时执行了足够的解析,以确保至少有一个方法具有合适数量的参数 - 这在 C# 5 规范的第 7.5.4 节中指定,但这并没有影响有效的返回类型。)

From the C# 5 spec, section 7.6.5:来自 C# 5 规范的第 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 .主表达式具有编译时类型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.可选参数列表的至少一个参数具有编译时类型dynamic并且主表达式没有委托类型。

In this case the compiler classifies the invocation-expression as a value of type dynamic .在这种情况下,编译器将调用表达式分类为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 is Foo总是bool
  • d as Foo is always Foo d as Foo总是Foo
  • new Foo(d) is always Foo even though the exact constructor to use is determined at execution time new Foo(d)总是Foo即使要使用的确切构造函数是在执行时确定的

But any method call is treated as having a return type of dynamic .但是任何方法调用都被视为具有返回类型dynamic

It's how dynamic works.这就是动态的工作原理。 From MSDN来自MSDN

Overload resolution occurs at run time instead of at compile time if one or more of the arguments in a method call have the type dynamic, or if the receiver of the method call is of type dynamic.如果方法调用中的一个或多个参数具有动态类型,或者方法调用的接收者是动态类型,则重载解决发生在运行时而不是编译时。

You might think that you don't have any additional overloads for your method but you might have.您可能认为您的方法没有任何额外的重载,但您可能有。 Compiler doesn't perform that check at compile time so that's why you see the type of dynaPlayer as dynamic instead of Player .编译器不会在编译时执行该检查,所以这就是为什么您将dynaPlayer的类型视为动态而不是Player

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM