Tôi đang làm việc trên một điều khiển có thể thực hiện một số kiểu dữ liệu khác nhau (bất kỳ thứ gì triển khai IComparable).Chuyển đổi loại chung mà không có rủi ro Ngoại lệ
tôi cần để có thể so sánh chúng với một biến khác thông qua vào.
Nếu datatype chính là một DateTime, và tôi đã thông qua một String, tôi cần phải
- nỗ lực để chuyển đổi Chuỗi thành một DateTime để thực hiện so sánh ngày tháng.
- nếu không thể chuyển đổi chuỗi thành DateTime, sau đó thực hiện so sánh Chuỗi.
Vì vậy, tôi cần một cách tổng quát để cố gắng chuyển đổi từ bất kỳ loại nào thành bất kỳ loại nào. Dễ dàng, .Net cung cấp cho chúng tôi lớp học TypeConverter.
Bây giờ, tốt nhất tôi có thể làm việc để xác định xem Chuỗi có thể được chuyển đổi thành DateTime hay không là sử dụng ngoại lệ. Nếu ConvertFrom đưa ra một ngoại lệ, tôi biết tôi không thể thực hiện chuyển đổi và phải thực hiện so sánh chuỗi.
Sau đây là tốt nhất mà tôi nhận được:
string theString = "99/12/2009";
DateTime theDate = new DateTime (2009, 11, 1);
IComparable obj1 = theString as IComparable;
IComparable obj2 = theDate as IComparable;
try
{
TypeConverter converter = TypeDescriptor.GetConverter (obj2.GetType());
if (converter.CanConvertFrom (obj1.GetType()))
{
Console.WriteLine (obj2.CompareTo (converter.ConvertFrom (obj1)));
Console.WriteLine ("Date comparison");
}
}
catch (FormatException)
{
Console.WriteLine (obj1.ToString().CompareTo (obj2.ToString()));
Console.WriteLine ("String comparison");
}
Một phần của tiêu chuẩn của chúng tôi ở trạng thái công việc mà:
Exceptions chỉ nên được nâng lên khi một tình huống ngoại lệ - tức. một lỗi gặp phải.
Nhưng đây không phải là tình huống đặc biệt. Tôi cần một cách khác xung quanh nó.
Hầu hết các loại biến có phương thức TryParse trả về boolean để cho phép bạn xác định xem chuyển đổi có thành công hay không. Nhưng không có phương thức TryConvert nào có sẵn cho TypeConverter. CanConvertFrom chỉ làm mờ nếu có thể chuyển đổi giữa các loại này và không xem xét dữ liệu thực được chuyển đổi. Phương pháp IsValid cũng vô ích.
Bất kỳ ý tưởng nào?
EDIT
tôi không thể sử dụng AS và IS. Tôi không biết một trong hai kiểu dữ liệu ở thời gian biên dịch. Vì vậy, tôi không biết những gì để As và là để !!!
EDIT
Ok đóng đinh khốn. Nó không gọn gàng như Marc Gravells, nhưng nó hoạt động (tôi hy vọng). Cảm ơn bạn đã inpiration Marc. Sẽ làm việc trên làm sạch nó lên khi tôi nhận được thời gian, nhưng tôi đã có một chút stackfixes mà tôi có để có được trên với.
public static class CleanConverter
{
/// <summary>
/// Stores the cache of all types that can be converted to all types.
/// </summary>
private static Dictionary<Type, Dictionary<Type, ConversionCache>> _Types = new Dictionary<Type, Dictionary<Type, ConversionCache>>();
/// <summary>
/// Try parsing.
/// </summary>
/// <param name="s"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool TryParse (IComparable s, ref IComparable value)
{
// First get the cached conversion method.
Dictionary<Type, ConversionCache> type1Cache = null;
ConversionCache type2Cache = null;
if (!_Types.ContainsKey (s.GetType()))
{
type1Cache = new Dictionary<Type, ConversionCache>();
_Types.Add (s.GetType(), type1Cache);
}
else
{
type1Cache = _Types[s.GetType()];
}
if (!type1Cache.ContainsKey (value.GetType()))
{
// We havent converted this type before, so create a new conversion
type2Cache = new ConversionCache (s.GetType(), value.GetType());
// Add to the cache
type1Cache.Add (value.GetType(), type2Cache);
}
else
{
type2Cache = type1Cache[value.GetType()];
}
// Attempt the parse
return type2Cache.TryParse (s, ref value);
}
/// <summary>
/// Stores the method to convert from Type1 to Type2
/// </summary>
internal class ConversionCache
{
internal bool TryParse (IComparable s, ref IComparable value)
{
if (this._Method != null)
{
// Invoke the cached TryParse method.
object[] parameters = new object[] { s, value };
bool result = (bool)this._Method.Invoke (null, parameters);
if (result)
value = parameters[1] as IComparable;
return result;
}
else
return false;
}
private MethodInfo _Method;
internal ConversionCache (Type type1, Type type2)
{
// Use reflection to get the TryParse method from it.
this._Method = type2.GetMethod ("TryParse", new Type[] { type1, type2.MakeByRefType() });
}
}
}
Không thực sự, có những câu hỏi hiểu biết những gì loại sẽ được chuyển đổi sang. Ở đây tôi không. Câu trả lời cho câu hỏi đó không giúp tôi chút nào. –
Tốt. Đủ công bằng. – jason
Phew .. Tôi nghĩ rằng tôi sẽ nhận được câu hỏi của tôi đóng cửa. Ive đã dành giờ trên này .. ;-) –