我上控制工作,可以采取多种不同的数据类型(任何实现IComparable的)的。一般类型的转换,而不用担心例外
我需要能够在通过另一个变量来比较这些。
如果主数据类型是一个DateTime,和我通过一个字符串,我需要
- 尝试转换将字符串转换为日期时间以执行日期比较。
- 如果String不能转换为DateTime然后做一个字符串比较。
所以我需要一个通用的方法来尝试从任何类型转换为任何类型。很简单,.Net为我们提供了TypeConverter类。
现在,我可以工作要做,以确定是否该字符串可以转换为DateTime最好是使用异常。如果ConvertFrom引发异常,我知道我无法进行转换,必须进行字符串比较。
以下是我得到的最好:
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");
}
我们工作国家标准部分,其中:
例外只应在异常情况下提出的 - 即。遇到错误。
但是,这不是一个特殊的情况。我需要另一种方式。
大多数变量类型有一个TryParse方法,它返回一个布尔值,让你决定是否转换成功与否。但是没有TryConvert方法可用于TypeConverter。 CanConvertFrom只有当它是可能的这些类型之间的转换和犯规考虑要转换的实际数据dermines。 IsValid方法也没用。
任何想法?
编辑
我不能使用AS和IS。我不知道编译时的数据类型。所以我不知道该怎么做,是!
编辑
好钉的私生子。它不像Marc Gravells那样整洁,但它有效(我希望)。感谢Marc的启发。当我得到时间的时候,我会整理它,但我有一堆错误修正,我必须得到。
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() });
}
}
}
不是真的有问题知道什么类型将被转换为。在这里,我不。这个问题的答案根本不能帮助我。 – 2010-01-21 17:24:34
好。很公平。 – jason 2010-01-21 17:27:02
唷..我以为我会让我的问题关闭。我花了几个小时在这一个.. ;-) – 2010-01-21 17:28:37