使用動態類型
此 dynamic
類型是靜態類型,但 dynamic
類型的物件會略過靜態類型檢查。 在大多數情況下,其運作會像是具有 object
類型。 編譯器會假設 dynamic
項目支援任何作業。 因此,您無須判斷物件是從 COM API、動態語言 (例如 IronPython)、HTML 文件物件模型 (DOM)、反映或是程式其他地方取得其值。 不過,如果程式碼無效,則會在執行階段出現錯誤。
例如,如果下列程式碼中的執行個體方法 exampleMethod1
只有一個參數,則編譯器會將 ec.exampleMethod1(10, 4)
方法的第一個呼叫視為無效,因為其包含兩個引數。 呼叫會造成編譯器錯誤。 編譯器不會檢查 dynamic_ec.exampleMethod1(10, 4)
方法的第二個呼叫,因為 dynamic_ec
的類型為 dynamic
。 因此,不會報告編譯器錯誤。 不過,這項錯誤並不是永遠不會被發現。 錯誤會在執行階段出現,並造成執行階段例外狀況。
static void Main(string[] args)
{
ExampleClass ec = new ExampleClass();
// The following call to exampleMethod1 causes a compiler error
// if exampleMethod1 has only one parameter. Uncomment the line
// to see the error.
//ec.exampleMethod1(10, 4);
dynamic dynamic_ec = new ExampleClass();
// The following line is not identified as an error by the
// compiler, but it causes a run-time exception.
dynamic_ec.exampleMethod1(10, 4);
// The following calls also do not cause compiler errors, whether
// appropriate methods exist or not.
dynamic_ec.someMethod("some argument", 7, null);
dynamic_ec.nonexistentMethod();
}
class ExampleClass
{
public ExampleClass() { }
public ExampleClass(int v) { }
public void exampleMethod1(int i) { }
public void exampleMethod2(string str) { }
}
上述範例中的編譯器角色,就是將每個陳述式應該對 dynamic
物件或運算式所進行之動作的相關資訊封裝在一起。 執行階段會檢查儲存的資訊,而任何無效的陳述式都會導致執行階段例外狀況。
大多數動態作業的結果本身就是 dynamic
。 例如,如果您在下列範例中將滑鼠指標停在 testSum
的使用用途上,IntelliSense 會顯示 (區域變數) dynamic testSum 類型。
dynamic d = 1;
var testSum = d + 3;
// Rest the mouse pointer over testSum in the following statement.
System.Console.WriteLine(testSum);
結果不是 dynamic
的作業包括:
- 從
dynamic
轉換成另一種類型。 - 包含
dynamic
類型引數的建構函式呼叫。
例如,下列宣告中 testInstance
的類型是 ExampleClass
,而不是 dynamic
:
var testInstance = new ExampleClass(d);
轉換
動態物件和其他類型間的轉換很簡單。 轉換可讓開發人員在動態和非動態行為之間進行切換。
您可以隱含地將任何項目轉換為 dynamic
,如下列範例所示。
dynamic d1 = 7;
dynamic d2 = "a string";
dynamic d3 = System.DateTime.Today;
dynamic d4 = System.Diagnostics.Process.GetProcesses();
相反地,您可以動態地將任何隱含轉換套用至類型 dynamic
的任何運算式。
int i = d1;
string str = d2;
DateTime dt = d3;
System.Diagnostics.Process[] procs = d4;
dynamic 類型引數的多載解析
如果方法呼叫中有一或多個引數的類型為 dynamic
,或如果方法呼叫的接收端類型為 dynamic
,則會在執行階段 (而不是編譯時期) 發生多載解析。 在下列範例中,如果唯一可存取的 exampleMethod2
方法會採用字串引數,則將 d1
作為引數傳送不會造成編譯器錯誤,但會造成執行階段例外狀況。 多載解析會在執行階段失敗,因為 d1
的執行階段類型為 int
,而 exampleMethod2
需要字串。
// Valid.
ec.exampleMethod2("a string");
// The following statement does not cause a compiler error, even though ec is not
// dynamic. A run-time exception is raised because the run-time type of d1 is int.
ec.exampleMethod2(d1);
// The following statement does cause a compiler error.
//ec.exampleMethod2(7);
Dynamic Language Runtime
動態語言執行階段 (DLR) 提供的基礎結構支援 C# 中的 dynamic
類型,也支援實作 IronPython 和 IronRuby 之類的動態程式設計語言。 如需 DLR 的詳細資訊,請參閱 Dynamic Language Runtime 概觀。
COM Interop
許多 COM 方法允許針對引數類型和傳回型別進行變化,方法是將類型指定為 object
。 COM Interop 需要對值進行明確轉型,才能與 C# 中的強型別變數配合使用。 如果您使用 EmbedInteropTypes (C# 編譯器選項) 選項進行編譯,則引進 dynamic
類型可讓您將 COM 簽章中出現的 object
項目視為具有 dynamic
類型,藉此避免大部分的轉型。 如需搭配 COM 物件使用 dynamic
類型的詳細資訊,請參閱如何使用 C# 功能存取 Office Interop 物件的文章。
相關文章
標題 | 描述 |
---|---|
dynamic | 說明如何使用 dynamic 關鍵字。 |
Dynamic Language Runtime 概觀 | 提供 DLR 概觀,DLR 是在 Common Language Runtime (CLR) 中新增一組動態語言服務的執行階段環境。 |
逐步解說:建立和使用動態物件 | 針對建立自訂動態物件及建立存取 IronPython 程式庫的專案,提供逐步指示。 |