C# 为什么VS2010 IntelliSense在使用动态参数链接方法时失败
我想向各位C#4.0动态方面的专家介绍一下 我有一个fluent builder类来帮助在创建对象之前配置它。此接口有一个方法SetParameters(…): 公共FluentBuilder设置参数(动态参数) { _参数=参数; 归还这个; } 我这样做是为了使用fluent界面:C# 为什么VS2010 IntelliSense在使用动态参数链接方法时失败,c#,visual-studio-2010,c#-4.0,C#,Visual Studio 2010,C# 4.0,我想向各位C#4.0动态方面的专家介绍一下 我有一个fluent builder类来帮助在创建对象之前配置它。此接口有一个方法SetParameters(…): 公共FluentBuilder设置参数(动态参数) { _参数=参数; 归还这个; } 我这样做是为了使用fluent界面: var order = new Order(); /* Setting up parameters */ dynamic parameters = new ExpandoObject(); parameter
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();
var order=新订单();
/*设置参数*/
动态参数=新的ExpandooObject();
parameters.Transaction=transactionObj;
parameters.CurrentPrincipal=Thread.CurrentPrincipal;
var proxiedOrder=ObjectProxyFactory
.配置(订单)
.FilterMethods(o=>o.InsertOrder())
.AddPreDecoration(AppConcerns.JoinSqlTransaction)
.AddPreDecoration(AppConcerns.EnterLog)
.AddPostDecoration(AppConcerns.ExitLog)
.AddPostDecoration(AppConcerns.SecurityCheck)
.SetParameters(参数)
.Teste()//此方法在fluent builder中不存在
.CreateProxy();
var result=proxiedOrder.InsertOrder();
正如上面的代码片段中所评论的,名为Teste()的方法在fluent接口中不存在,但intelissense允许在调用SetParameters后写入anymethod,就像它返回dynamic一样,但正如您在代码中看到的,SetParameters返回的FluentInterface不是动态的
上述代码在运行时由成功编译将失败,因为在运行时,在FluentBuilder类中找不到方法Teste()
为了在设计时解决此问题,并获得正确的Intelissense,我需要将参数强制转换为ExpandooObject类:
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();
var proxiedOrder=ObjectProxyFactory
.配置(订单)
.FilterMethods(o=>o.InsertOrder())
.AddPreDecoration(AppConcerns.JoinSqlTransaction)
.AddPreDecoration(AppConcerns.EnterLog)
.AddPostDecoration(AppConcerns.ExitLog)
.AddPostDecoration(AppConcerns.SecurityCheck)
.SetParameters((ExpandoObject)参数)//转换为ExpandoObject
.Teste()//现在intelissense给了我一个“红色”错误,解决方案将无法编译
.CreateProxy();
var result=proxiedOrder.InsertOrder();
我发现,每当我在任何方法链接中传递一个C#dynamic参数时,在该方法接收到动态参数后,对方法的后续调用将表现为返回一个C#dynamic对象,即使该方法的返回类型不是动态的
是虫子吗?或者这是预料中的事?这是预料中的事。任何涉及动态参数的方法调用都是动态解析的-确切的重载直到执行时才能确定,因此在编译时返回类型未知,因此它被视为
动态的
。在某些情况下,C#编译器可以推断出更多信息(例如,如果是静态方法调用),但为简单起见,它不能推断。只有少数涉及动态值的变量表达式具有非动态类型。(从内存中,is
运算符始终为bool
,并且构造函数始终假定返回正在构造的类型。)
编辑:我终于找到了规范参考。根据第7.6.5节:
如果以下至少一项成立,则调用表达式被动态绑定(§7.2.2):
- 主表达式具有编译时类型dynamic
- 可选参数列表中至少有一个参数具有编译时类型dynamic,并且主表达式没有委托类型
这是预料之中的事。任何涉及动态参数的方法调用都是动态解析的-确切的重载直到执行时才能确定,因此在编译时返回类型未知,因此它被视为
动态的
。在某些情况下,C#编译器可以推断出更多信息(例如,如果是静态方法调用),但为简单起见,它不能推断。只有少数涉及动态值的变量表达式具有非动态类型。(从内存中,is
运算符始终为bool
,并且构造函数始终假定返回正在构造的类型。)
编辑:我终于找到了规范参考。根据第7.6.5节:
如果以下至少一项成立,则调用表达式被动态绑定(§7.2.2):
- 主表达式具有编译时类型dynamic
- 可选参数列表中至少有一个参数具有编译时类型dynamic,并且主表达式没有委托类型
感谢您的澄清,现在我知道如果一个方法有一个动态参数,那么按照惯例,在使用方法链接时,结果将在设计时被视为动态的。但我不同意这一点,因为调用的方法有一个IDE可以在设计时推断的返回。为什么一个动态参数可以改变一个定义了返回类型的方法的结果?所以,是的,我们不能绝对确定你是否在链接-我们决定不给你intellisense。谢谢你的澄清,现在我知道如果一个方法有一个动态参数,然后,按照惯例,在使用方法链接时,结果将在设计时被视为动态的。但我不同意这一点,因为调用的方法有一个IDE可以在设计时推断的返回。为什么一个动态参数可以改变一个定义了返回类型的方法的结果?所以,是的,我们不能绝对确定你是否在链接-我们决定根本不给你intellisense
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();