为什么在使用动态参数链接方法时VS2010 IntelliSense失败 [英] Why VS2010 IntelliSense fails when chaining methods with dynamic args

查看:94
本文介绍了为什么在使用动态参数链接方法时VS2010 IntelliSense失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想向您解释C#4.0动态专家。

I would like some explanation of you experts in C# 4.0 dynamic.

我有一个熟练的生成器类,可以帮助在创建对象之前对其进行配置。该接口具有方法SetParameters(...):

I have a fluent builder class to help configure an object before creating it. This interface has a method SetParameters(...):

    public FluentBuilder<TInterface> SetParameters(dynamic parameters)
    {
        _parameters = parameters;
        return this;
    }

我这样做是为了消耗流畅的界面:

I'm doing this to consume the fluent interface:

var order = new Order();

/* Setting up parameters */
dynamic parameters = new ExpandoObject();
parameters.Transaction = transactionObj;
parameters.CurrentPrincipal = Thread.CurrentPrincipal;

var proxiedOrder = ObjectProxyFactory
    .Configure<IOrder>(order)
    .FilterMethods(o => o.InsertOrder())
    .AddPreDecoration(AppConcerns.JoinSqlTransaction)
    .AddPreDecoration(AppConcerns.EnterLog)
    .AddPostDecoration(AppConcerns.ExitLog)
    .AddPostDecoration(AppConcerns.SecurityCheck)
    .SetParameters(parameters)
    .Teste() //this method doesn't exist in the fluent builder
    .CreateProxy();

var result = proxiedOrder.InsertOrder();

如上述代码段所述,流畅的接口中不存在称为Teste()的方法,但是intelissense允许我在调用SetParameters之后像返回动态代码一样编写任何方法,但是正如您在代码中看到的那样,SetParameters返回的不是动态的FluentInterface。

As commented in the above snippet, the method called Teste() doesn't exists in the fluent interface, but intelissense allow write anymethod after I call SetParameters like it returning dynamic, but as you see in code, SetParameters returns FluentInterface that is not dynamic.

上面的代码已成功编译在运行时by将失败,因为在运行时将在FluentBuilder类中找不到Teste()方法。

The code above compiles sucessfully by in runtime will fail because in runtime the method Teste() will not be found in FluentBuilder class.

在设计时解决此问题并获得正确的Intelissense ,我需要将参数转换为ExpandoObject类:

To resolve this problem in design-time, and to get correct Intelissense, I need to cast the parameter to the ExpandoObject class:

var proxiedOrder = ObjectProxyFactory
.Configure<IOrder>(order)
.FilterMethods(o => o.InsertOrder())
.AddPreDecoration(AppConcerns.JoinSqlTransaction)
.AddPreDecoration(AppConcerns.EnterLog)
.AddPostDecoration(AppConcerns.ExitLog)
.AddPostDecoration(AppConcerns.SecurityCheck)
.SetParameters((ExpandoObject)parameters) //cast to ExpandoObject
.Teste() //now intelissense is giving me an "red" error and solution will not compile
.CreateProxy();

var result = proxiedOrder.InsertOrder();

我发现,只要在任何方法链中传递C#动态参数,该方法之后接收到动态参数后,对方法的后续调用将类似于返回C#动态对象,即使该方法的返回类型不是动态的。

I've found that, anytime I pass a C# dynamic parameter in any method chaining, after that method receiving the dynamic parameter, the subsequent calls to methods will behave like returning a C# dynamic object, even if the return type of the method it's not dynamic.

这是一个错误?还是会发生这种情况?

Is it a bug ? Or is this expected to happens ?

推荐答案

会发生这种情况。任何涉及动态参数的方法调用都是动态解决的-确切的重载直到执行时才能确定,因此返回类型在编译时是未知的,因此将其视为 dynamic 。在某些情况下,C#编译器可以推断出更多信息(例如,如果是静态方法调用),但为简单起见,它不能。只有很少一些涉及动态值的表达式具有非动态类型。 (从内存中, is 运算符始终为 bool ,并且始终假定构造函数返回正在构造的类型。 )

It's expected to happen. Any method call involving a dynamic argument is resolved dynamically - the exact overload can't be determined until execution time, so the return type is unknown at compile time, so it's treated as being dynamic. In some cases the C# compiler could infer more information (e.g. if it's a static method call) but for simplicity it doesn't. Only a variable few expressions involving dynamic values have non-dynamic types. (From memory, the is operator is always bool, and a constructor is always assumed to return the type being constructed.)

编辑:我终于找到了规范参考。从第7.6.5节开始:

I've finally found the spec reference. From section 7.6.5:


如果至少有以下一项成立,则动态绑定调用表达式(第7.2.2节):

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


  • 主表达式的编译时类型为动态。

  • 可选参数列表的至少一个参数具有编译时

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

In this case the compiler classifies the invocation-expression as a value of type dynamic.

这篇关于为什么在使用动态参数链接方法时VS2010 IntelliSense失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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