2010-08-12 37 views
7

Sự khác biệt giữa một biến được khai báo là động và một biến được khai báo là System.Object là gì? Chạy chức năng sau đây sẽ dường như chỉ ra rằng cả hai biến được đúc để đúng loại động:Sự khác nhau giữa động và System.Object

void ObjectTest() 
{ 
    System.Object MyTestVar = "test"; 
    dynamic MyTestVar2 = "Testing 123"; 

    Console.WriteLine("{0}", MyTestVar.GetType()); 
    Console.WriteLine("{0}", MyTestVar2.GetType()); 

    MyTestVar = 123; 
    MyTestVar2 = 321; 

    Console.WriteLine("{0}", MyTestVar.GetType()); 
    Console.WriteLine("{0}", MyTestVar2.GetType()); 
} 
+1

Tôi đã viết một bài đăng về điều này một thời gian trước đây: http://blogs.msdn.com/b/csharpfaq/archive/2010/01/25/what-is-the-difference-between-dynamic-and-object -keywords.aspx –

Trả lời

6

Sự khác biệt là MyTestVar2.ToUpper() biên dịch và các công trình, mà không cần bất kỳ đúc rõ ràng.

object là loại bình thường.
dynamic về cơ bản là một loại trình giữ chỗ khiến trình biên dịch phát ra các cuộc gọi kết thúc động.

GetType() là hàm bình thường được xác định bởi lớp object hoạt động trên cá thể mà bạn gọi.
GetType() hoàn toàn không bị ảnh hưởng bởi loại được khai báo của một biến đề cập đến đối tượng bạn gọi nó. (ngoại trừ các giá trị rỗng)

+0

vì vậy những gì bạn đang nói là bạn có thể gọi các phương thức đối tượng cụ thể trên các biến động? – Icemanind

+2

Bạn có thể gọi phương thức _any_ trên các biến 'dynamic'. Mã 'động x = 3; x.Explode(); 'sẽ biên dịch hoàn toàn tốt – SLaks

1

Có lẽ bạn nên bắt đầu với điều này tuyệt vời MSDN article. Sự khác biệt có thể được tóm tắt khá ngắn gọn:

Tại thời gian biên dịch, một yếu tố đó là gõ như động được giả định để hỗ trợ bất kỳ hoạt động.

System.Object chỉ có một số ít các hoạt động mà nó hỗ trợ - ToString(), Equals() vv

1

Sự khác biệt cơ bản là thời gian biên dịch (đối với đối tượng) vs thời gian chạy (đối với động) resoulution của cuộc gọi. Nó cũng được gọi là sớm và muộn ràng buộc. [Chú ý: thêm một tham chiếu đến Microsoft.CSharp cho đoạn mã sau để biên dịch.]

object o = "Hello world";// fine because a derived type can be assigned to a base type 
    dynamic d= "Hello world";// fine as well 

    Type otype=o.GetType();// compiles because it confirms that object has a GetType() 
    Type dtype=d.GetType();// also compiles but for another reason (i.e.no binding yet) 

    string upperd= d.ToUpper(); // compiles because no binding yet (anything goes :) 
    string uppero= o.ToUpper(); // Fails to compile. Object has no ToUpper() method 

Nếu bạn nhận xét ra các cuộc gọi cuối cùng, ứng dụng sẽ chạy tốt vì CLR, khi nó đạt đến giây cuối cùng gọi d .ToUpper() tại thời gian chạy, nó sẽ tìm kiếm một phương thức ToUpper() trong kiểu chuỗi và sẽ tìm thấy nó ở đó (vì trong câu lệnh thứ hai d đã được gán một chuỗi). Cuộc gọi cuối cùng không biên dịch vì ToUpper() đã được tìm kiếm trong kiểu System.Object tại thời gian biên dịch mà tất nhiên sẽ không có ở đó.

Các vấn đề liên quan