我想对 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();
正如在上面的代码片段中所评论的那样,调用 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# 动态对象,即使方法的返回类型不是动态的。
这是一个错误吗?还是预计会发生这种情况?