2010-02-01 18 views
10

Tôi đã phát hiện ra rằng nếu tôi chạy theo các dòng mã.Tại sao gọi một số chức năng của lớp Object, trên một thể loại nguyên thủy, cần boxing?

int i = 7; 
i.GetHashCode(); //where GetHashCode() is the derived 
       //function from System.Object 

Không đấm bốc được thực hiện, nhưng nếu tôi gọi i.GetType() (một chức năng có nguồn gốc từ System.Object) ở vị trí của GetHashCode(), một đấm bốc sẽ được yêu cầu gọi GetType(), Tại sao nó không thể gọi GetType() vào loại dụ thô sơ trực tiếp , không có quyền anh, trong khi có thể gọi GetHashCode() mà không có quyền anh?

+0

Tôi ngạc nhiên rằng 'GetType' được gọi là gì cả. Vì C# được nhập tĩnh và một biến kiểu giá trị * không thể chứa bất kỳ thứ gì ngoài các đối tượng của kiểu giá trị, kiểu này có thể được định nghĩa ở kiểu biên dịch (đó là 'typeof (int)'). Vì vậy, tại sao phát hành một cuộc gọi thời gian chạy? –

+0

Đúng vậy nhưng ý định ở đây là để làm rõ điều đó, tại sao mọi thứ không hoạt động theo cách họ cần. – waheed

Trả lời

8

Chìa khóa ở đây là GetType() không phải là ảo và không thể bị ghi đè. Vì cấu trúc có hiệu quả là sealed, nên không thể ghi đè các phương thức hơn so với cấu trúc, do đó thời gian chạy và trình biên dịch có thể xử lý các phương pháp struct đã bị ghi đè làm cuộc gọi tĩnh.

Nếu bạn viết một struct (hiếm) bạn nên ghi đè lên tất cả các phương pháp như ToString(), Equals(), GetHashCode() vì lý do chính xác này. Nếu bạn không phải hộp. Tuy nhiên, GetType()không thể bị ghi đè, do đó cần quyền anh.

Điều này thực sự dẫn đến một số lẻ cạnh trường hợp với Nullable<T> và đấm bốc, vì một sản phẩm nào Nullable<T> hộp để null, vì vậy:

int i = obj.GetHashCode(); // fine 
Type t = obj.GetType(); // boom 
2

Tôi nghĩ lý do là GetHashCode được thực hiện trên System.Int32 trực tiếp, bạn gọi System.Int32 :: GetHashCode(). Không cần phải hộp nếu bạn gọi một hàm thành viên đã biết trên một kiểu giá trị.

+0

Vì vậy, các chức năng không được thực hiện trên System.Int32 trực tiếp, giống như các chức năng từ System.ValueType hoặc System.Object không thể được gọi trực tiếp? – waheed

+0

Đó là những gì ildasm đã chỉ cho tôi cho đến nay .... Khi bạn gọi hàm lớp cơ sở (như System.Object :: GetType() boxing là cần thiết. Nếu bạn gọi một hàm được thực hiện trên đối tượng value thì không có boxing là nessecary ... – Arve

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