将动态对象传递给 C# 方法会更改返回类型 [英] Passing dynamic object to C# method changes return type

查看:18
本文介绍了将动态对象传递给 C# 方法会更改返回类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个继承 DynamicObject 的 并且想要创建一个静态方法,该方法可以创建具有预定属性的新实例(存储在 Dictionary 中).

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
        };
    }
}

用法:

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

既然方法签名只有一个,那为什么传入一个动态返回一个动态对象呢?或者实际上只是 Visual Studio 2013 感到困惑?

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?

推荐答案

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

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.6.5 节:

From the C# 5 spec, section 7.6.5:

一个调用表达式在至少满足以下条件之一的情况下被动态绑定:

An invocation-expression is dynamically bound if at least one of the following holds:

  • primary-expression 具有编译时类型 dynamic.
  • 可选argument-list 的至少一个参数具有编译时类型dynamic 并且primary-expression 没有委托类型.
  • 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.

在这种情况下,编译器将 invocation-expression 分类为 dynamic 类型的值.[...]

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 总是 bool
  • d as Foo 总是 Foo
  • new Foo(d) 总是 Foo 即使要使用的确切构造函数是在执行时确定的
  • 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

但是任何方法调用都被视为具有 dynamic 的返回类型.

But any method call is treated as having a return type of dynamic.

这篇关于将动态对象传递给 C# 方法会更改返回类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆