C# 4.0 提供了 dynamic 寫法,讓 C# 有了弱類型語言的特性,在編譯時期不檢查其用法正確性,而是在 Runtime 時期才檢查,這也意味著編寫程式時不能使用 “intellisense” 功能。
Code 1
dynamic str = "Iverson.Hong";
Console.WriteLine(str); // Iverson.Hong
int len = str.Length;
Console.WriteLine(len); // 12
len = str.length; // Runtime exception
Console.WriteLine(len);
string upperStr = str.ToUpper();
Console.WriteLine(upperStr); // IVERSON.HONG
upperStr = str.toUpper(); // Runtime exception
Console.WriteLine(upperStr);
在編譯時期完全沒有錯誤,但一執行則出現 exception
使用 dynamic 物件時應搭配 try catch 來處理才是比較正確的寫法,
dynamic str = "Iverson.Hong";
try
{
Console.WriteLine(str); // Iverson.Hong
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
try
{
int len = str.Length;
Console.WriteLine(len); // 12
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
try
{
int len = str.length; // Runtime exception
Console.WriteLine(len);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
try
{
string upperStr = str.ToUpper();
Console.WriteLine(upperStr); // IVERSON.HONG
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
try
{
string upperStr = str.toUpper(); // Runtime exception
Console.WriteLine(upperStr);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Result 1
Iverson.Hong
12
'string' 不包含 'length' 的定義
IVERSON.HONG
'string' 不包含 'toUpper' 的定義
Code 2
Code 2 的用法比較接近實際的用法,Template class 時在編譯時期無法操作實際帶入類別的 Method 或 Property,這時可利用 dynamic 來操作。
class A
{
public string Name { get; set; }
public int Age { get; set; }
}
class B
{
public string Name { get; set; }
public string Gender { get; set; }
}
class Test<T> where T : class
{
T _t;
public Test(T t)
{
_t = t;
}
public void Print()
{
dynamic d = _t;
PropertyInfo property = typeof(T).GetProperty("Name");
if (property != null &&
property.PropertyType.Name == "String")
{
Console.WriteLine(d.Name);
}
if (typeof(T).Name == "A")
{
if (typeof(T).GetProperty("Age") != null &&
typeof(T).GetProperty("Age").PropertyType.Name == "Int32")
Console.WriteLine(d.Age.ToString());
}
else if (typeof(T).Name == "B")
{
if (typeof(T).GetProperty("Gender") != null &&
typeof(T).GetProperty("Gender").PropertyType.Name == "String")
Console.WriteLine(d.Gender);
}
}
}
Client端程式:
A a = new A { Name = "Iverson", Age = 30};
B b = new B { Name = "Hong", Gender = "Male"};
Test<A> test1 = new Test<A>(a);
test1.Print();
Test<B> test2 = new Test<B>(b);
test2.Print();
Result 2
Iverson
30
Hong
Male