[英]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.