繁体   English   中英

为什么使用动态参数链接方法时VS2010 IntelliSense失败

[英]Why VS2010 IntelliSense fails when chaining methods with dynamic args

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

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

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

我这样做是为了使用流畅的界面:

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();

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

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

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

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#动态对象,即使该方法的返回类型不是动态。

是虫子吗? 还是预期会发生这种情况?

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

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

如果下列条件之一成立,则调用绑定是动态绑定的(第7.2.2节):

  • 主表达式具有动态的编译时类型。
  • 可选参数列表的至少一个参数的编译时类型为dynamic,而主表达式没有委托类型。

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

暂无
暂无

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

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