【发布时间】:2009-07-09 23:33:31
【问题描述】:
我有以下场景,我想传入字符串和泛型类型:
public class Worker {
public void DoSomeWork<T>(string value)
where T : struct, IComparable<T>, IEquatable<T> { ... }
}
在某些时候,我需要将字符串值转换为其T 值。但我不想直接转换,因为如果字符串无法转换为类型T,我需要执行一些逻辑。
我在想我可以尝试使用 Convert.ChangeType() 但这有一个问题,如果它不转换它会抛出异常,我将经常运行 DoSomeWork() 方法,而不必依赖try/catch 判断转换是否有效。
所以这让我想到,我知道我将使用数字类型,因此 T 将是以下任何一种:int、uint、short、ushort、long、@ 987654331@、byte、sbyte、decimal、float、double。知道这一点后,我认为可能会提出一个更快的解决方案,因为我知道我将使用数字类型(请注意,如果 T 不是数字类型,我会抛出异常)...
public class NumericWorker {
public void DoSomeWork<T>(string value)
where T : struct, IComparable<T>, IEquatable<T>
{
ParseDelegate<T> tryConverter =
SafeConvert.RetreiveNumericTryParseDelegate<T>();
...
}
}
public class SafeConvert
{
public delegate bool ParseDelegate<T>(string value, out T result);
public static ParseDelegate<T> RetreiveNumericTryParseDelegate<T>()
where T : struct, IComparable<T>, IEquatable<T>
{
ParseDelegate<T> tryParseDelegate = null;
if (typeof(T) == typeof(int))
{
tryParseDelegate = (string v, out T t) =>
{
int typedValue;
bool result = int.TryParse(v, out typedValue);
t = result ? (T)typedValue : default(T);
//(T)Convert.ChangeType(typedValue, typeof(T)) : default(T);
return result;
};
}
else if (typeof(T) == typeof(uint)) { ... }
else if (typeof(T) == typeof(short)) { ... }
else if (typeof(T) == typeof(ushort)) { ... }
else if (typeof(T) == typeof(long)) { ... }
else if (typeof(T) == typeof(ulong)) { ... }
else if (typeof(T) == typeof(byte)) { ... }
else if (typeof(T) == typeof(sbyte)) { ... }
else if (typeof(T) == typeof(decimal)) { ... }
else if (typeof(T) == typeof(float)) { ... }
else if (typeof(T) == typeof(double)) { ... }
return tryParseDelegate;
}
}
但是上面的问题是我不能写t = result ? (T)typedValue : default(T);,因为typedValue 到T 的转换会导致问题,到目前为止我能够解决它的唯一方法是写@987654342 @。但如果我这样做,我只是在做另一个转换。
因此我想知道是否有人知道我可以如何解决这个问题(如果您认为执行 ChangeType() 是一个问题),或者是否有更好的解决方案我没有考虑过。
【问题讨论】: