2012-02-24 23 views
15

Tôi có đoạn code dưới đây và tôi cần phải chuyển đổi một chuỗi để một kiểu mà cũng được quy định từ String:Làm thế nào để chuyển đổi một chuỗi thành một kiểu dữ liệu khó hiểu nào được xác định khi chạy?

Type t = Type.GetType("System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"); 

      object d = Convert.ChangeType("2012-02-23 10:00:00", t); 

tôi nhận được thông báo lỗi dưới đây:

Invalid cast from 'System.String' to 'System.Nullable`1[[System.DateTime, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]'. 

Làm thế nào sẽ là độc đáo có thể?

Tôi biết một cách xấu xí sẽ được kiểm tra xem loại là nullable sử dụng nếu:

Type possiblyNullableType = Type.GetType("System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"); 

    var underlyingType = Nullable.GetUnderlyingType(possiblyNullableType); 

    Object result; 

    // if it's null, it means it wasn't nullable 
    if (underlyingType != null) 
    { 
     result = Convert.ChangeType("2012-02-23 10:00:00", underlyingType); 
    } 

Nên có bất kỳ cách nào tốt hơn?

Xin cảm ơn,

Trả lời

29

Có hai vấn đề .

Thứ nhất, Convert.ChangeType chỉ đơn giản là không hỗ trợ các loại không có giá trị.

Thứ hai, ngay cả khi nó đã làm, bằng cách kết quả đấm bốc (gán nó cho một số object), bạn đã chuyển đổi nó thành một số DateTime.

Bạn có thể trường hợp đặc biệt các loại nullable:

string s = "2012-02-23 10:00:00"; 
Type t = Type.GetType("System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]"); 
object d; 

if (t.IsGenericType && t.GetGenericTypeDefinition() == typeof(Nullable<>)) 
{ 
    if (String.IsNullOrEmpty(s)) 
     d = null; 
    else 
     d = Convert.ChangeType(s, t.GetGenericArguments()[0]); 
} 
else 
{ 
    d = Convert.ChangeType(s, t); 
} 
+0

Tại sao bạn cần kiểm tra t.IsGenericType? phần t.GetGenericTypeDefinition() == typeof (Nullable <>) sẽ bao gồm; phải không? –

+2

@William 'GetGenericTypeDefinition()' ném ngoại lệ nếu loại không phải là chung chung. – hvd

1

Điều gì đó tương tự? Trừ khi bạn thực sự cần phải làm điều đó một cách năng động.

if (string.IsNullOrEmpty(input)) 
{ 
    return new DateTime?(); 
} 
else 
{ 
    return new DateTime?(DateTime.Parse(input)); 
} 

Có thể bạn có thể kiểm tra xem loại của bạn là một trong những loại 'nullable' và sau đó có thể bạn có thể tìm thấy một cái gì đó hữu ích ở đây:

Convert string to nullable type (int, double, etc...)

+0

Tôi có thể' t chỉ định DateTime, nó được xác định khi chạy. –

+0

'return new DateTime?();' Nên được thay thế bằng 'return null;'. – ken2k

+0

Có lẽ nếu bạn có thể cung cấp thêm một số thông tin về những gì bạn đang cố gắng làm trái với những gì bạn hiện đang làm, chúng tôi có thể tư vấn cho bạn? – Paddy

9

tôi viết dưới đây phương pháp helper generic mà làm việc trong hầu hết các kịch bản (không được thử nghiệm với các kiểu generic):

static void Main(string[] args) 
{ 
    Object result = 
     ConvertValue(
      "System.Nullable`1[[System.DateTime, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", 
      "2012-02-23 10:00:00"); 
} 

public static Object ConvertValue(string typeInString, string value) 
{ 
    Type originalType = Type.GetType(typeInString); 

    var underlyingType = Nullable.GetUnderlyingType(originalType); 

    // if underlyingType has null value, it means the original type wasn't nullable 
    object instance = Convert.ChangeType(value, underlyingType ?? originalType); 

    return instance; 
} 
+0

Cảm ơn bạn. Đây là giải pháp thanh lịch và làm việc tốt nhất. –

2
public static T GetValue<T>(string Literal, T DefaultValue) 
    { 
     if (Literal == null || Literal == "" || Literal == string.Empty) return DefaultValue; 
     IConvertible obj = Literal; 
     Type t = typeof(T); 
     Type u = Nullable.GetUnderlyingType(t); 

     if (u != null) 
     { 
      return (obj == null) ? DefaultValue : (T)Convert.ChangeType(obj, u); 
     } 
     else 
     { 
      return (T)Convert.ChangeType(obj, t); 
     } 
    } 
Các vấn đề liên quan