2011-12-18 28 views
18

Những gì tôi muốn làm là một cái gì đó như thế này:C# Phản ánh: Làm thế nào để có được loại Nullable <int>?

switch(myObject.GetType().GetProperty("id")) 
{ 
    case ??: 
     // when Nullable<Int32>, do this 
    case ??: 
     // when string, do this 
    case ??: 
     // when Nullable<bool>, do this 

đường gì dưới object.GetType() sẽ có tên chuỗi của các kiểu dữ liệu mà tôi có thể so sánh bằng một tuyên bố trường hợp? Tôi cần phải biết loại vì vậy tôi có thể có một trong nhiều Convert.ToInt32 (chuỗi) mà sẽ thiết lập giá trị của myObject bằng cách sử dụng Reflection.

+1

này gần như chắc chắn làm những điều sai trái. Tại sao bạn không thể tận dụng lợi thế của đa hình, thay vì sử dụng một tuyên bố chuyển đổi khổng lồ? –

+0

Nếu bạn đang đề xuất tạo một số hàm với các kiểu tham số khác nhau, tôi có thể. Trong trường hợp này, tôi đang sao chép một tập các thuộc tính của các kiểu khác nhau từ một đối tượng này sang một đối tượng khác, trong đó một kiểu luôn luôn là một kiểu chuỗi. Vì vậy, tôi cần phải chuyển đổi giá trị để gán nó. Điều đó và tôi có rất ít kinh nghiệm với Reflection. –

+0

@CodyGray anh ấy có thể đang làm một cái gì đó liên quan đến sự phản ánh, nói rằng viết ORM của riêng mình. Hoặc viết một serializer tùy chỉnh cho tất cả các DAO này, bạn không bao giờ biết. – nawfal

Trả lời

8

Cập nhật: Có vẻ như C# 7 sẽ hỗ trợ chuyển đổi trên Type s khi người hỏi câu hỏi này đang cố gắng thực hiện. Đó là một chút khác nhau mặc dù vậy xem ra cho mìn cú pháp.

Bạn không cần một tên chuỗi để so sánh nó:

if (myObject.GetType().GetProperty("id").PropertyType == typeof(Nullable<Int32>)) 
    // when Nullable<Int32>, do this 
else if (myObject.GetType().GetProperty("id").PropertyType == typeof(string)) 
    // when string, do this 
else if (myObject.GetType().GetProperty("id").PropertyType == typeof(Nullable<bool>)) 
    // when Nullable<bool>, do this 
+1

Bạn có chắc chắn bạn so sánh .GetType() để typeof (Nullable ) hoặc là nó một tài sản thuộc GetType()? Giả sử int? và Nullable là cùng loại, a.GetType()! = typeof (Nullable ). –

+0

Bạn có thể phải làm điều này với câu lệnh 'if', thay vì trong câu lệnh' switch'. Nhưng, giống như bạn, tôi chưa bao giờ làm điều này trước đây. Nó trông giống như một mô hình chống lại tôi. –

+0

VS studio sẽ có cuộc tấn công hoảng loạn trong chuyển đổi mã trên (myObject.GetType()) sẽ hiển thị một lỗi IDE của "Giá trị của tích phân loại dự kiến" và trường hợp typeof (XXX) sẽ hiển thị một lỗi IDE của "giá trị gia tăng liên tục được mong đợi" – heads5150

0

Như @Cody Gray nói nếu phát biểu có lẽ sẽ là cách tốt nhất

var t = myObject.GetType(); 

if (t == typeof(Nullable<int>)) 
{ } 
else if (t == typeof(string)) 
{} 
else if (t==typeof(Nullable<bool>)) 
{} 
+2

thú vị đủ, khi 'int? a = 3' thì 'typeof (a)' là "System.Int32" –

+1

@ Dr.Zim: Xem giải thích tại đây: http://stackoverflow.com/questions/785358/nullable-type-is-not-a-nullable -type –

+1

@ Dr.Zim 'typeof (a)' thậm chí không biên dịch. Đó là 'a.GetType()' trả về 'int'. – CodesInChaos

44

Tôi đã sử dụng sau loại mã để kiểm tra xem loại có thể vô hiệu hóa không và để có loại thực tế:

if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)) 
{ 
    return Nullable.GetUnderlyingType(type); 
} 

Nếu loại đó là Nullable mã này trả về phần int (loại cơ bản). Nếu bạn chỉ cần chuyển đổi đối tượng thành loại cụ thể, bạn có thể sử dụng phương thức System.Convert.ChangeType.

+0

+1 và đáng chú ý phương thức này thực hiện cùng một kiểm tra bên trong và trả về null nếu kiểu đã cho không phải là 'typeof (Nullable <>) 'do đó làm một kiểm tra null sau đó thay vì tuyên bố nếu cũng sẽ làm việc. – Connell

16

Câu hỏi rất khó hiểu. Là "myObject" đối tượng có thể là một int vô giá trị? Hoặc là thuộc tính "id" có thể có kiểu nullable int?

Nếu trước đây, câu hỏi của bạn không thể trả lời được vì nó giả định giả mạo. Không có thứ gì như một cái hộp có thể bỏ được. Tôi lưu ý rằng tất cả các câu trả lời đề xuất if (myobject.GetType() == typeof(int?)) do đó không chính xác; điều kiện sẽ không bao giờ đúng.

Khi bạn chuyển đổi một giá trị rỗng thành đối tượng, nó trở thành tham chiếu null (nếu int vô giá trị không có giá trị) hoặc nó trở thành một hộp int. Không có cách nào để xác định xem một đối tượng có chứa một int vô giá trị không bởi vì một đối tượng không bao giờ chứa một hàm có thể vô hiệu.

Nếu sau, so sánh loại thuộc tính đến typeof(int?). Bạn không thể sử dụng công tắc; chỉ các hằng số có thể được sử dụng cho các trường hợp chuyển đổi và các loại không phải là hằng số.

Tất cả những gì đã nói, đây là một mùi mã xấu. Tại sao bạn sử dụng sự phản chiếu ngay từ đầu?

+0

Cập nhật: trong C# 7, câu lệnh chuyển đổi không còn yêu cầu biểu thức liên tục :) –

+0

Và cung cấp cơ chế để chuyển đổi trên các loại. Tính năng đó được đề xuất lần đầu tiên vào năm 2001? Tôi nghĩ. Vì vậy, 16 năm, không tệ. –

2

Trong .net, trường hợp của các loại giá trị chỉ là các tập hợp các bit, không có thông tin loại liên quan. Tuy nhiên, đối với mọi loại giá trị khác ngoài Nullable<T>, hệ thống cũng tự động tạo loại lớp tương ứng có nguồn gốc từ System.ValueType. Một chuyển đổi mở rộng tồn tại từ loại giá trị cho loại lớp được tạo tự động và chuyển đổi thu hẹp từ loại lớp được tạo tự động thành loại giá trị. Trong trường hợp Nullable<T>, không có loại lớp được tạo tự động tương ứng với các chuyển đổi đến/từ loại giá trị; thay vào đó, mở rộng chuyển đổi tồn tại theo cả hai hướng giữa Nullable<T> và loại lớp được liên kết với T.

Theo như tôi có thể nói, hành vi kỳ lạ này được thực hiện để cho phép so sánh giữa null và trống Nullable<T> để trả về giá trị đúng.

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