2008-11-20 13 views
11

Tôi đang làm việc trên một công cụ mà tôi cần phải chuyển đổi các giá trị chuỗi thành các loại đối tượng thích hợp của chúng. Ví dụ. chuyển đổi một chuỗi như "2008-11-20T16:33:21Z" thành giá trị DateTime. Các giá trị số như "42""42.42" phải được chuyển đổi thành giá trị Int32 và giá trị tương ứng là Double.Cách xác định xem một chuỗi có phải là số trong C#

Cách tiếp cận tốt nhất và hiệu quả nhất để phát hiện xem chuỗi là số nguyên hay số? Có phải Int32.TryParse hoặc Double.TryParse cách để đi không?

Trả lời

9

Về mặt hiệu quả, có, TryParse thường là tuyến đường ưu tiên.

Nếu bạn có thể biết (ví dụ, bằng cách phản chiếu) các loại mục tiêu trước - nhưng không muốn phải sử dụng một switch khối lớn, bạn có thể quan tâm trong việc sử dụng TypeConverter - ví dụ:

 DateTime foo = new DateTime(2008, 11, 20); 
     TypeConverter converter = TypeDescriptor.GetConverter(foo); 
     string s = converter.ConvertToInvariantString(foo); 
     object val = converter.ConvertFromInvariantString(s); 
20

Int.TryParseDouble.TryParse có lợi ích thực sự là trả về số.

Điều gì đó giống như Regex.IsMatch("^\d+$") có nhược điểm là bạn vẫn phải phân tích cú pháp chuỗi một lần nữa để nhận giá trị.

+0

Lợi ích khác được thêm vào là phương pháp TryParse trả về biến boolean, vì vậy rất dễ viết mã cho các kịch bản thành công và lỗi của bạn khi phân tích cú pháp số. –

+0

nhưng nếu bạn chỉ quan tâm nếu đó là số nguyên hay không, TryParse có lợi thế là yêu cầu bạn khai báo biến cho tham số ngoài –

2

Tôi muốn giới thiệu cá nhân .TryParse(). Đó là những gì tôi sử dụng dù sao đi nữa. Đó là nếu dữ liệu của bạn sẽ sai ngay bây giờ và một lần nữa. Nếu bạn chắc chắn các chuỗi đến sẽ có thể chuyển đổi thành số nguyên hoặc tăng gấp đôi mà không bị cản trở, .Parse() nhanh hơn.

Dưới đây là một thú vị link để hỗ trợ điều này.

0

Giữ ý tưởng về công cụ chuyển đổi để bỏ qua khối chuyển đổi, bạn có thể sử dụng khái niệm Nhập Vịt. Về cơ bản, bạn muốn biến một chuỗi thành X, vì vậy bạn tạo một phương thức gọi X.TryParse (chuỗi, x X) nếu X có TryParse trên đó, nếu không bạn không bận tâm (Hoặc tôi giả sử bạn có thể ném một lỗi). Bạn sẽ làm điều này như thế nào? Phản ánh và Generics.

Về cơ bản, bạn sẽ có một phương pháp sẽ lấy một loại và sử dụng sự phản chiếu để xem nó có TryParse trên nó hay không. Nếu bạn tìm thấy một phương pháp như vậy thì bạn gọi nó và trả lại bất cứ thứ gì TryParse quản lý để có được. Điều này hoạt động tốt với bất kỳ loại giá trị nào như nói Decimal hoặc DateTime.

public static class ConvertFromString 
{ 
    public static T? ConvertTo<T>(this String numberToConvert) where T : struct 
    { 
    T? returnValue = null; 

    MethodInfo neededInfo = GetCorrectMethodInfo(typeof(T)); 
    if (neededInfo != null && !numberToConvert.IsNullOrEmpty()) 
    { 
     T output = default(T); 
     object[] paramsArray = new object[2] { numberToConvert, output }; 
     returnValue = new T(); 

     object returnedValue = neededInfo.Invoke(returnValue.Value, paramsArray); 

     if (returnedValue is Boolean && (Boolean)returnedValue) 
     { 
     returnValue = (T)paramsArray[1]; 
     } 
     else 
     { 
     returnValue = null; 
     }  
    } 

    return returnValue; 
    } 
} 

đâu GetCorrectMethodInfo sẽ giống như thế này:

private static MethodInfo GetCorrectMethodInfo(Type typeToCheck) 
{ 

    MethodInfo returnValue = someCache.Get(typeToCheck.FullName); 

    if(returnValue == null) 
    { 
    Type[] paramTypes = new Type[2] { typeof(string), typeToCheck.MakeByRefType() }; 
    returnValue = typeToCheck.GetMethod("TryParse", paramTypes); 
    if (returnValue != null) 
    { 
     CurrentCache.Add(typeToCheck.FullName, returnValue); 
    } 
    } 

    return returnValue; 
} 

Và sử dụng sẽ là:

decimal? converted = someString.ConvertTo<decimal>(); 

Tôi ghét cắm bản thân mình, nhưng tôi đã này giải thích đầy đủ ở đây:

GetCorrectMethodInfo

Rest of It