2010-10-05 7 views

Trả lời

18
type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>) 

Bạn cũng có thể tìm thấy Nullable.GetUnderlyingType(Type nullableType) hữu ích, dễ dàng có được những T của typeof(Nullable<T>) bạn vượt qua trong

+0

Rất tốt! Cảm ơn. (Tôi luôn luôn quên về '<>' trong sự phản ánh.) –

+0

Điều này sẽ không làm việc trong nhiều tình huống phổ biến kể từ khi CLR xử lý 'Nullable ' như là một loại đặc biệt. Đặc biệt, nó được đóng hộp vào một 'T' đóng hộp. – Ani

+0

@Ani: ý của bạn là gì? Bởi 'T', tôi đang đề cập đến' typeof (T) ' – thecoop

7

Mặc dù câu trả lời @ theCoop là chính xác (không có gì về cơ bản là sai khi đặt mã của anh ấy vào phần thân của phương thức bạn đã cung cấp), có một số gotchas khổng lồ ở đây.

Nullable<T> được xử lý theo thời gian chạy dưới dạng loại 'đặc biệt' có một số ngữ nghĩa rất đặc biệt. Đặc biệt, khi một Nullable<T> được đóng hộp:

  1. Nếu HasValue == true, nó hoạt động giống như một đóng hộp T, làm cho nó không thể cho mã downsteam nói nếu đối tượng tạo ra được sản xuất bởi đấm bốc một T hoặc bằng cách đấm bốc một Nullable<T>. Mở hộp đến TNullable<T> đều có thể.
  2. Nếu HasValue == false, quyền anh chỉ trả lại null. Mở hộp đến T sẽ ném, mở hộp đến Nullable<T> sẽ thành công, trong đó HasValue == false.

Trong cả hai trường hợp, boxedNullableObject.GetType() sẽ không tiết lộ rằng đối tượng được tạo ra bởi quyền anh là Nullable<T>. Tôi không thể nghĩ ra bất kỳ loại giá trị nào khác thể hiện hành vi lạ như vậy.

Ví dụ, hãy xem xét:

// Output: "System.Nullable`1[System.Int32]" 
Console.WriteLine(typeof(int?)); 


object boxedNullableInt32WithValue = new int?(0); 

// Output: "System.Int32", NOT "System.Nullable`1[System.Int32]" 
Console.WriteLine(boxedNullableInt32WithValue.GetType()); 


object boxedNullableInt32WithoutValue = new int?(); 

// NullReferenceException is thrown 
Console.WriteLine(boxedNullableInt32WithoutValue.GetType()); 

Do đó, viết một phương pháp như:

public static bool IsObjectANullableT(this object obj) { ... }

là một ý tưởng thực sự xấu.

EDIT: Trên một lưu ý khác, tôi vừa nhận ra có một phương pháp khung làm những gì bạn cần bằng kỹ thuật tương tự như mẫu của @ theCoop: Nullable.GetUnderlyingType.

Cách sử dụng:

static bool IsNullable(Type type) 
{ 
    return Nullable.GetUnderlyingType(type) != null; 
} 

EDIT: Chỉ cần thấy rằng đây cũng đã được đề cập bởi @TheCoop trong câu trả lời của mình. Lỗi của tôi.

+0

Các điểm rất quan trọng và hữu ích cần đề cập.May mắn thay, tôi đã đặc biệt tìm cách xác định nếu thuộc tính 'PropertyType' của' PropertyInfo' là một số kiểu nullable; trong trường hợp này, câu trả lời của thecoop hoạt động rất tốt. Nhưng bạn nói đúng rằng [không có loại giá trị nào khác hoạt động theo cách đó] (http://stackoverflow.com/questions/3775582/how-is-the-boxing-unboxing-behavior-of-nullablet-possible). –

+0

Haha, thật tuyệt vời: bạn chỉ cho tôi một câu hỏi khác về * của bạn * đề cập đến vấn đề này, ngoại trừ với sự rõ ràng và chi tiết hơn. Thật là một tập thể dục trong dư thừa một phần của tôi. – Ani

+0

Không hề! Tôi không nghĩ câu trả lời này là thừa; nó cung cấp một số hiểu biết rất quan trọng về những cạm bẫy tiềm năng của một giải pháp chung cho vấn đề tôi đặt ra trong câu hỏi của mình. Tôi chỉ đưa vào liên kết đó bởi vì tôi cảm thấy nó chạm vào một số vấn đề tương tự, đối với những người tìm kiếm thêm thông tin. –