Nếu bạn có một bộ loại được xác định để chuyển đổi, bạn có thể thực hiện một loạt if/elseif/elseif/else
(hoặc switch/case
trên tên loại) để phân phối về phương pháp phân tích chuyên biệt. Điều này sẽ khá nhanh. Điều này được mô tả trong @Fabio's answer.
Nếu bạn vẫn còn có vấn đề hiệu suất, bạn cũng có thể tạo ra một bảng tra cứu sẽ cho phép bạn thêm các phương pháp phân tích mới như bạn cần phải hỗ trợ họ:
Với một số giấy gói phân tích cơ bản:
public delegate bool TryParseMethod<T>(string input, out T value);
public interface ITryParser
{
bool TryParse(string input, out object value);
}
public class TryParser<T> : ITryParser
{
private TryParseMethod<T> ParsingMethod;
public TryParser(TryParseMethod<T> parsingMethod)
{
this.ParsingMethod = parsingMethod;
}
public bool TryParse(string input, out object value)
{
T parsedOutput;
bool success = ParsingMethod(input, out parsedOutput);
value = parsedOutput;
return success;
}
}
Sau đó, bạn có thể thiết lập trình trợ giúp chuyển đổi thực hiện tra cứu và gọi trình phân tích cú pháp thích hợp:
public static class DataConversion
{
private static Dictionary<Type, ITryParser> Parsers;
static DataConversion()
{
Parsers = new Dictionary<Type, ITryParser>();
AddParser<DateTime>(DateTime.TryParse);
AddParser<int>(Int32.TryParse);
AddParser<double>(Double.TryParse);
AddParser<decimal>(Decimal.TryParse);
AddParser<string>((string input, out string value) => {value = input; return true;});
}
public static void AddParser<T>(TryParseMethod<T> parseMethod)
{
Parsers.Add(typeof(T), new TryParser<T>(parseMethod));
}
public static bool Convert<T>(string input, out T value)
{
object parseResult;
bool success = Convert(typeof(T), input, out parseResult);
if (success)
value = (T)parseResult;
else
value = default(T);
return success;
}
public static bool Convert(Type type, string input, out object value)
{
ITryParser parser;
if (Parsers.TryGetValue(type, out parser))
return parser.TryParse(input, out value);
else
throw new NotSupportedException(String.Format("The specified type \"{0}\" is not supported.", type.FullName));
}
}
Sau đó sử dụng có thể như sau:
//for a known type at compile time
int value;
if (!DataConversion.Convert<int>("3", out value))
{
//log failure
}
//or for unknown type at compile time:
object value;
if (!DataConversion.Convert(myType, dataValue, out value))
{
//log failure
}
Điều này có thể có các generics được mở rộng để tránh object
đấm bốc và loại đúc, nhưng khi nó đứng này hoạt động tốt; có lẽ chỉ tối ưu hóa khía cạnh đó nếu bạn có một hiệu suất đo lường được từ nó.
EDIT: Bạn có thể cập nhật phương thức DataConversion.Convert
để nếu không có công cụ chuyển đổi được chỉ định đã đăng ký, nó có thể quay trở lại phương thức TypeConverter
hoặc ném ngoại lệ thích hợp. Tùy thuộc vào bạn nếu bạn muốn nắm bắt tất cả hoặc chỉ đơn giản là có các loại được hỗ trợ được xác định trước và tránh bị try/catch
lặp lại. Khi nó đứng, mã đã được cập nhật để ném một NotSupportedException
với một thông báo cho biết loại không được hỗ trợ. Vui lòng tinh chỉnh vì điều đó có ý nghĩa. Hiệu suất khôn ngoan, có lẽ nó làm cho tinh thần để làm catch-tất cả như có lẽ những người sẽ ít hơn và xa giữa một khi bạn chỉ định chuyên ngành phân tích cú pháp cho các loại phổ biến nhất được sử dụng.
Nếu bạn biết 'loại', bạn _could_ thử theo cách thủ công các phương thức' TryParse' khác nhau của mỗi người và xem điều đó có hữu ích không. –
Bạn có đang cố gắng nhấn từng trình phân tích cú pháp loại để xem trình phân tích cú pháp nào tương thích với mục nhập CSV không? Tức là, trước tiên bạn thử 'DateTime', sau đó bạn thử' int', sau đó bạn thử 'decimal', sau đó bạn thử' double', sau đó bắt tất cả thành 'string'? Hoặc bạn có _know_ rằng một mục nào đó _should_ là 'DateTime', nhưng đôi khi/thường dữ liệu có định dạng không chính xác? –
Ngoài ra, bạn có đang thực hiện điểm chuẩn này trong chế độ 'release' hoặc chế độ' debug', hoặc với trình gỡ lỗi đính kèm không? Nếu ở chế độ 'debug', nó có thể đang báo cáo/lưu trữ thông tin ngoại lệ/ngăn xếp quá mức cho các mục đích gỡ lỗi. –