2012-05-23 24 views
19
int a = 2; 

Console.WriteLine(a.ToString()); // displays 2 

// definition of ToString() here - public override string ToString(); 

Bây giờ, đây là một số hiểu biết của tôi:Nếu cấu trúc không thể kế thừa một lớp hoặc cấu trúc khác, tại sao Int32 có một phương thức ToString()?

  1. Tất cả các lớp trong .net có được một phương pháp ToString(), được thừa kế từ lớp Object.
  2. Cấu trúc không thể bắt nguồn từ lớp hoặc cấu trúc khác. int là cấu trúc kiểu Int32, được một số phương pháp ToString() [Với tham số] từ Giao diện mà nó thực hiện.
  3. Ngoài ra còn có một ToString() [mà không params] chức năng trong struct Int32

Theo http://msdn.microsoft.com/en-us/library/system.int32.tostring.aspx,

struct Int32 đè ValueType.ToString phương pháp()

Nếu một struct không thể kế thừa một số lớp hoặc cấu trúc, bạn có thể giải thích phương thức ToString() này có sẵn cho Int32 không?

+0

tất cả các loại có nguồn gốc từ Object bằng cách nào đó. int lấy được từ ValueType xuất phát từ Object. Giả định của bạn 2 là sai. http://ptgmedia.pearsoncmg.com/images/chap13_0321169514/elementLinks/13fig02.gif – 0lukasz0

+0

@ 0lukasz0 [Không * mọi thứ * xuất phát từ đối tượng] (http://blogs.msdn.com/b/ericlippert/archive/2009/ 08/06/not-everything-derives-from-object.aspx). – vcsjones

+0

"struct Int32 ghi đè phương thức ValueType.ToString()" trả lời câu hỏi của riêng bạn. –

Trả lời

30

Nếu một struct không thể kế thừa một số lớp hoặc struct,

Điều này không đúng. Tất cả các cấu trúc (và các kiểu giá trị tích hợp, như System.Int32, System.Single, v.v.) luôn luôn kế thừa hoàn toàn từ System.ValueType (trong đó, lần lượt, được kế thừa từ System.Object).

Tuy nhiên, bạn không thể tạo cấu trúc thừa kế từ bất kỳ điều gì khác.

Đây rõ ràng là đánh vần ra trong ngôn ngữ C# spec, 4.1.1:

4.1.1 Các loại System.ValueType

Tất cả các loại giá trị mặc nhiên thừa hưởng từ System.ValueType lớp, mà , lần lượt, kế thừa từ đối tượng lớp. Không thể cho bất kỳ loại nào xuất phát từ một loại giá trị, và do đó các loại giá trị được niêm phong hoàn toàn (§10.1.1.2).

Sau đó, sau này (4.1.3) struct được một cách rõ ràng định nghĩa là một loại giá trị:

4.1.3 Struct loại

Một loại struct là một loại giá trị mà có thể khai báo các hằng , các trường, phương thức, thuộc tính, các chỉ mục, các toán tử, các hàm tạo mẫu, các hàm tạo tĩnh và các kiểu lồng nhau.

+0

Vì vậy, nếu tôi đang tạo một cấu trúc tùy chỉnh mới, tôi không thể kế thừa từ bất kỳ lớp nào khác, nhưng cấu trúc hiện có được kế thừa từ ValueType? Bạn có thể xác nhận không? – robot

+5

@robot * Tất cả các cấu trúc * kế thừa từ 'ValueType', ngay cả những cấu trúc bạn tạo, ngay cả khi bạn không tuyên bố rõ ràng rằng nó kế thừa từ ValueType (mà bạn không thể làm ngay cả khi bạn muốn). – vcsjones

+0

Cảm ơn câu trả lời của bạn – robot

1

Int32 thực hiện IFormattable, trong đó xác định phương pháp ToString

+2

IFormattable định nghĩa một phương thức ToString được tham số hóa, không phải phương thức ToString không tham số mà OP đang hỏi. – phoog

1

Mỗi định nghĩa của một loại có nguồn gốc từ ValueType thực sự xác định hai loại khác nhau của sự vật trong thời gian chạy: một loại đối tượng heap (mà xuất phát từ ValueType và trong chuyển từ Object và có chứa thông tin loại được nhúng) và một loại vị trí lưu trữ (không chứa bất kỳ thông tin loại được nhúng nào, nhưng thay vào đó yêu cầu mã sử dụng nó phải có một số phương tiện khác để biết nó là gì). Một thể hiện của kiểu đối tượng heap chứa một trường kiểu vị trí lưu trữ và mã cố gắng truy cập this sẽ truy cập trường đó. Nếu một kiểu giá trị được đặt ngầm hoặc rõ ràng đến một vị trí lưu trữ của kiểu tham chiếu, hệ thống sẽ tạo một đối tượng heap mới với kiểu thích hợp và sao chép tất cả các trường công khai và riêng tư của kiểu giá trị vào các trường tương ứng trong đối tượng heap. Nếu đối tượng heap được truyền tới một vị trí lưu trữ kiểu giá trị, tất cả các trường công khai và riêng tư từ đối tượng heap sẽ được sao chép vào vị trí lưu trữ kiểu giá trị.

Nếu cố gắng sử dụng bất kỳ Object hoặc phương thức giao diện nào trên đối tượng heap của một loại giá trị, phương thức sẽ được gọi giống như bất kỳ phương pháp đối tượng đống nào khác. Nếu nỗ lực được thực hiện trên một vị trí lưu trữ kiểu giá trị, đối với bất kỳ phương thức nào khác ngoài GetType, trình biên dịch sẽ tạo ra một mã opcode "bị ràng buộc" đặc biệt, thông báo thời gian chạy của loại vị trí lưu trữ và chỉ thị Runtime để gọi địa chỉ phương pháp phù hợp với loại đó. Vì trình biên dịch sẽ có sẵn loại vị trí lưu trữ và thời gian chạy có thể sử dụng để tìm phương thức thích hợp, phương thức thích hợp có thể được gọi trực tiếp trên vị trí lưu trữ mà không phải tạo đối tượng heap mới trước. GetType là một ngoại lệ đáng chú ý; vì nó hoạt động bằng cách kiểm tra thông tin kiểu được nhúng trong một đối tượng, nó chỉ có thể hoạt động trên những thứ có thông tin kiểu được nhúng. Do đó, đối số của nó sẽ được chuyển đổi thành dạng đối tượng đống trước cuộc gọi; GetType sau đó sẽ có thể kiểm tra thông tin loại được nhúng của đối tượng heap đó.

+0

Bạn có đang cố gắng tránh sử dụng cụm từ * boxing * (hoặc bất kỳ biến thể nào của chúng) không? –

+0

@BenVoigt: Tôi sẽ không ngờ rằng việc gọi 'ToString' trên một 'Int32' sẽ liên quan đến boxing [nó có thể được định nghĩa theo kiểu như đòi hỏi quyền anh, nhưng tôi không thể nghĩ tại sao nó lại là].Có thể nói rằng quá trình chuyển đổi một đối tượng thành dạng đối tượng heap của nó được gọi là boxing, nhưng tôi không chắc chắn làm thế nào và tốt nhất để nói điều đó mà không mất tập trung từ điểm chính, đó là quá trình như vậy không cần thiết khi gọi 'Int32.ToString()'. – supercat

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