This article is currently in the process of being translated into Vietnamese (~81% done).
The ExpandoObject
Như chúng ta thấy trong bài trước, chúng ta có thể dùng từ khóa dynamic để lưu đối tượng mà chúng ta định nghĩa thuộc tính không cần khai báo class. Những gì chúng ta không thể làm với đối tượng dynamic đó là thêm thuộc tính vào nó sau khi đã khởi tạo đối tượng/ Nếu bạn cần thì có giải pháp cho bạn : đó là ExpandoObject. Hãy xem ví dụ sau, như thế bạn có thể thấy nó rất đơn giản và dễ dùng:
dynamic user = new System.Dynamic.ExpandoObject();
user.Name = "John Doe";
user.Age = 42;
user.HomeTown = "New York";
Console.WriteLine(user.Name + " is " + user.Age + " years old and lives in " + user.HomeTown);
Bạn sẽ thấy rằng tôi khai báo đối tượng với kiểu dynamic, thậm chí tôi khởi tạo một ExpandoObject. Lí do là nếu đơi tượng được khai báo là một ExpandoObject thì trình biên dịch có thể kiểm tra và ngay lập tức báo thiếu thuộc tính (Name, Age …). Chúng ta có thể tránh điều này bằng cách khai báo nó là dynamic, như vậy trình biên dịch sẽ không kiểm tra.
Một điều thú vị là ExpandoObject có thuộc tính cũng có thể là ExpandoObject khác. Để dễ hình dung thì chúng ta xem ví dụ sau :
dynamic user = new System.Dynamic.ExpandoObject();
user.Name = "John Doe";
user.Age = 42;
user.HomeTown = new System.Dynamic.ExpandoObject();
user.HomeTown.Name = "New York";
user.HomeTown.ZipCode = 10001;
Console.WriteLine(user.Name + " is " + user.Age + " years old and lives in " + user.HomeTown.Name + " [" + user.HomeTown.ZipCode + "]");
Tôi chỉ đơn giản thay đổi HomeTown từ chuỗi sang ExpandoObject, và sau đó thêm thuộc tính vào nó , trong trường hợp này là tên và mã zip của thành phố. Nhưng không dừng lại ở đó – chúng ta có thể thêm phương thức vào đối tượng, và xem ví dụ sau :
user.DescribeUser = (Func<String>)(() => {
return user.Name + " is " + user.Age + " years old and lives in " + user.HomeTown.Name + " [" + user.HomeTown.ZipCode + "]";
});
Console.WriteLine(user.DescribeUser());
Pretty neat stuff, but what IS an ExpandoObject really? It implements several interesting interfaces, but one of them is IDictionary<string, object> - this means that underneath all the syntactical sugar, your ExpandoObject is basically just a dictionary which holds object values based on string keys. That also means that iterating over an ExpandoObject is just as easy as iterating through a regular Dictionary. This is very practical:
dynamic user = new System.Dynamic.ExpandoObject();
user.Name = "John Doe";
user.Age = 42;
foreach (KeyValuePair<string, object> kvp in user)
{
Console.WriteLine(kvp.Key + ": " + kvp.Value);
}
Summary
Kiểu ExpandoObject cho phép bạn định nghĩa đối tượng trực tiếp và sau đó thêm thuộc tính vào nó bất cứ khi nào bạn muốn. Vì nó là kiểu dynamic nên nó thừa kế các ưu điểm và nhược điểm như chúng ta đã bàn ở bài trước. Hơn nữa, ExpandoObject thực hiện InotifyPropertyChange và bạn sẽ thích khi bạn dùng ví dụ WPF trong ứng dụng.