呼叫擴充方法時傳入 dynamic 型別參數,發生以下錯誤:
'Blah' has no applicable method named 'ExtMethod' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.
使用以下範例可重現錯誤,ExtMethod 為擴充方法,傳入字串參數時正常,改傳 dynamic 型別即出現上述錯誤:
想起先前遇過類似狀況:【茶包射手日記】CSHTML ViewBag無法使用擴充方法,因 ViewBag 為 dynamic 型別無法使用擴充方法,解法很簡單,將 dynamic 轉型就好。在本案例,也是改寫成 b.ExtMethod((string)d) 就能解決問題。
這讓我聯想到另一個狀況,撇開擴充方法不論,多載(Overloading)方法會依參數型別呼叫不同方法,遇上參數型別是 dynamic 會發生什麼事?
依據 C# 程式規格,dynamic 本質上可視為多了部分特異功能的 object:
dynamic is considered identical to object except in the following respects:
- Operations on expressions of type dynamic can be dynamically bound (Dynamic binding).
- Type inference (Type inference) will prefer dynamic over object if both are candidates.
Because of this equivalence, the following holds:
- There is an implicit identity conversion between object and dynamic, and between constructed types that are the same when replacing dynamic with object
- Implicit and explicit conversions to and from object also apply to and from dynamic.
- Method signatures that are the same when replacing dynamic with object are considered the same signature
- The type dynamic is indistinguishable from object at run-time.
- An expression of the type dynamic is referred to as a dynamic expression.
簡單來說,面多載抉擇時,把 dynamic 想成 object 就對了~