Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么VS2010 IntelliSense在使用动态参数链接方法时失败_C#_Visual Studio 2010_C# 4.0 - Fatal编程技术网

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

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

我想向各位C#4.0动态方面的专家介绍一下

我有一个fluent builder类来帮助在创建对象之前配置它。此接口有一个方法SetParameters(…):

公共FluentBuilder设置参数(动态参数) { _参数=参数; 归还这个; } 我这样做是为了使用fluent界面:

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,并且主表达式没有委托类型
在这种情况下,编译器将调用表达式分类为dynamic类型的值


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

编辑:我终于找到了规范参考。根据第7.6.5节:

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

  • 主表达式具有编译时类型dynamic
  • 可选参数列表中至少有一个参数具有编译时类型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();