vdh*_*ant 19 .net c# generics casting
我有以下场景,我想传入字符串和泛型类型:
public class Worker {
public void DoSomeWork<T>(string value)
where T : struct, IComparable<T>, IEquatable<T> { ... }
}
Run Code Online (Sandbox Code Playgroud)
在某些方面我需要将字符串值转换为其T值.但我不想做直接转换,因为如果字符串无法转换为类型,我需要执行一些逻辑T.
我在想我可以尝试使用,Convert.ChangeType()但这有一个问题,如果它不转换它将抛出异常,我将DoSomeWork()经常运行该方法,不必依赖try/catch来确定转换是否是有效.
因此,这让我思考,我知道,我将与数字类型来工作,因此T将是下列任何一项:int,uint,short,ushort,long,ulong,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;
}
}
Run Code Online (Sandbox Code Playgroud)
但上述有,我不能写的问题t = result ? (T)typedValue : default(T);作为铸造typedValue到T原因的问题,我已经能够通过编写绕过它迄今是唯一的出路(T)Convert.ChangeType(typedValue, typeof(T)).但如果我这样做,我只是做另一个转换.
因此,我想知道是否有人知道我如何解决这个问题(如果你认为这ChangeType()是一个问题)或者如果有一个更好的解决方案我没有考虑过.
Sho*_*og9 40
t =结果?(T)typedValue:默认(T);
尝试:
t = result ? (T)(object)typedValue : default(T);
Run Code Online (Sandbox Code Playgroud)
是的,仿制药有时会有点烦人.
FWIW,我用一个更简单的包装周围Convert.ChangeType(),只是做了预检查空字符串.除非您将此用于未经检查的用户输入,否则这可能就足够了.
Ree*_*sey 12
鉴于这种:
因此T将是以下任何一种:int,uint,short,ushort,long,ulong,byte,sbyte,decimal,float,double.
我建议只使用Convert.ChangeType,而不用担心它.只有当你的字符串格式错误时才会出现异常,在这种情况下,你可以返回默认值(T).
即:
try
{
result = Convert.ChangeType(value, typeof(T));
}
catch
{
result = default(T);
}
Run Code Online (Sandbox Code Playgroud)
ToType是这里的通用参数.这适用于可空类型,以防万一你需要它.您可以将主要方法提取为通用转换器,它将转换为任何类型,包括nullables.
ToType result = default(ToType);
result = ChangeType<ToType>(typedValue);
private T ChangeType<T>(object o)
{
Type conversionType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
return (T)Convert.ChangeType(o, conversionType);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
50112 次 |
| 最近记录: |