Sự khác biệt giữa System.Type và System.RuntimeType trong C # là gì?


89

Tôi đang cố gắng thực hiện một số bài kiểm tra quy ước ngày hôm nay và nhận được tất cả các loại trong một assembly (bằng cách gọi Assembly.GetTypes()), khi tôi tình cờ gặp một cái gì đó:

System.RuntimeType:[First.Namespace.FirstClass]

Bất cứ khi nào tôi cố gắng so sánh loại đó với typeof(FirstClass), chúng không bằng nhau. Vì vậy, khi tôi cố gắng tìm tất cả các kiểu có chứa FirstClassdưới dạng tham số chung, tôi không tìm thấy bất kỳ kiểu nào.

Sự khác biệt giữa System.RuntimeTypevà là System.Typegì?

Có cách nào để giải quyết vấn đề của tôi?


6
Bạn có thể cung cấp một chương trình nhỏ giải thích sự cố bạn đang gặp phải không?
Eric Lippert

Tôi đã đi, nhưng có câu trả lời đã: P
Edgar Gonzalez

Câu trả lời:


108

System.RuntimeTypelà một lớp cụ thể dẫn xuất từ ​​lớp cơ sở trừu tượng System.Type. Vì System.RuntimeTypekhông công khai, bạn thường sẽ gặp phải các trường hợp của nó như System.Type.

Sự nhầm lẫn có thể phát sinh khi bạn đang cố gắng lấy kiểu của một đối tượng và gọi nhầm GetType()một đối tượng khác đại diện cho kiểu của đối tượng đầu tiên, thay vì chỉ sử dụng trực tiếp đối tượng đó. Sau đó Type.ToString()sẽ trả về "System.RuntimeType"khi đối tượng mà nó được gọi đại diện cho một Loại:

string str = string.Empty;
Type strType = str.GetType();
Type strTypeType = strType.GetType();
strType.ToString();     // returns "System.string"
strTypeType.ToString(); // returns "System.RuntimeType"

Ví dụ: trong bài đăng blog này, ai đó đang cố gắng lấy loại cột trong cơ sở dữ liệu, hãy làm như sau:

object val = reader.GetFieldType(index);
Type runtimeType = val.GetType();
PropertyInfo propInfo = runtimeType.GetProperty("UnderlyingSystemType");
Type type = (Type)propInfo.GetValue(val, null);

Vì val đã là một đối tượng Kiểu nên val.GetType () sẽ trả về một đối tượng Kiểu khác đại diện cho kiểu System.RuntimeTimevì đây là kiểu cụ thể được sử dụng để đại diện cho đối tượng kiểu gốc. Bài đăng trên blog sau đó cho thấy một số thủ thuật phản ánh không cần thiết, để có được loại đối tượng loại ban đầu, khi thực sự tất cả những gì được yêu cầu là:

Type type = reader.GetFieldType(index) as Type;

Vì vậy, nếu Typeđối tượng của bạn đang báo cáo rằng nó đại diện cho a System.RuntimeType, hãy đảm bảo rằng bạn đã không vô tình gọi GetType()đến một kiểu mà bạn đã có.


Đoạn mã đầu tiên chỉ kiểm tra xem đối tượng có phải là một phiên bản của — Typenó sẽ trả về true ngay cả khi bạn vượt qua typeof(int). Đoạn mã thứ hai không hoạt động để so sánh typeof(string).GetType()typeof(Type).
Mark Cidade

Điều này thật đúng với gì mà tôi đã tìm kiếm! Tôi đã tìm thấy bài Thomas Danecker nhưng không Doogal Bell
Edgar Gonzalez

1
@Mark Cidade. Tốt phát hiện, cảm ơn. Có câu trả lời cố định để hữu ích hơn, hy vọng giải quyết bất kỳ sự nhầm lẫn nào mà tôi đã giới thiệu bằng cách trích dẫn bài đăng trên blog đó.
Ergwun

@Edgar Gonzalez: Bài đăng trên blog mà tôi đã tham khảo thực sự khá sai lệch. Vui lòng xem câu trả lời cập nhật của tôi để biết thông tin tốt hơn.
Ergwun

4

Từ câu trả lời cho Sự khác biệt giữa System.Type và System.RuntimeType của Thomas Danecker :

System.Type là một lớp cơ sở trừu tượng. CLR có sự triển khai cụ thể của nó trong kiểu nội bộ System.RuntimeType. Vì typeof (chuỗi) này .GetType () trả về kiểu RuntimeType nhưng typeof (Kiểu) trả về kiểu bình thường. Sử dụng phương thức .Equals trên thực tế là một đối tượng.ReferenceEquals trả về false. Để có được kết quả như mong đợi, bạn có thể sử dụng type.IsInstanceOfType (element). Điều này cũng sẽ trả về true nếu phần tử thuộc loại dẫn xuất. Nếu bạn muốn kiểm tra loại chính xác, giá trị trả về false của phương thức của bạn là kết quả mong muốn. Bạn cũng có thể sử dụng checkType (arrayType, Type.GetType ("System.RuntimeType")) để kiểm tra RuntimeType.


1
"does in fact an" - Chúng tôi có thể sửa ngữ pháp được không. Điều này giống như mấu chốt của toàn bộ sự việc và nó không có ý nghĩa.
N73k

2

Tóm lại...

    "".GetType().ToString()           == "System.String"

    "".GetType().GetType().ToString() == "System.RuntimeType"

Cách bây giờ tôi nghĩ về nó là System.Typekiểu cơ sở cho kiểu biểu thị kết quả yêu cầu kiểu đối tượng trong thời gian chạy, cụ thể là System.RuntimeType. Vì vậy, khi bạn yêu cầu kiểu của một đối tượng, như trong, "".GetType()thể hiện của được System.Typetrả về là nó là con cháu System.RuntimeType,. Trong thực tế, ta nên mong đợi rằng typeof(System.Type).GetType()sẽ System.RuntimeTypelà tốt, nhưng tôi nghĩ rằng khuôn khổ đặc biệt ngăn chặn điều này ... đối xứng.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.