我不得不为此抗争了一段时间。我正在使用AutoMapper在不同的数字格式之间进行映射,并且在将int映射到int时不断得到错误?等。现在,我可以修改我的DTO对象来匹配,但这并不容易。
我知道这主要是由于盒装类型,与AutoMapper无关,但如果能看到更多对类型转换的支持(比如强制隐式转换的标志,毕竟AutoMapper是一个助手库),那就太好了。
这里我们将使用自定义类型映射器:
Mapper.Initialize(cfg =>
{
// Here we're going to use some custom type converters
// The custom converter just forces a cast between two somewhat castable types using implicit conversion.
cfg.CreateMap<int, int?>().ConvertUsing<CastableTypeConverter<int, int?>>();
cfg.CreateMap<double, int?>().ConvertUsing<CastableTypeConverter<double, int?>>();
cfg.CreateMap<short, int?>().ConvertUsing<CastableTypeConverter<short, int?>>();
cfg.CreateMap<byte, int?>().ConvertUsing<CastableTypeConverter<byte, int?>>();
cfg.CreateMap<double, int>().ConvertUsing<CastableTypeConverter<double, int>>();
cfg.CreateMap<decimal, int>().ConvertUsing<CastableTypeConverter<decimal, int>>();
cfg.CreateMap<decimal, double>().ConvertUsing<CastableTypeConverter<decimal, double>>();
cfg.CreateMap<short, int>().ConvertUsing<CastableTypeConverter<short, int>>();
cfg.CreateMap<byte, int>().ConvertUsing<CastableTypeConverter<byte, int>>();
/*...*/
});
/// <summary>
/// This just forces implicit casting between two types (that are castable!)
/// Such as (int) to (int?), or (double) to (int)
/// </summary>
/// <typeparam name="TSrc"></typeparam>
/// <typeparam name="TDst"></typeparam>
private class CastableTypeConverter<TSrc, TDst> : TypeConverter<TSrc, TDst>
{
protected override TDst ConvertCore(TSrc source)
{
Type srcType = typeof(TSrc);
Type destType = typeof(TDst);
TDst result = Activator.CreateInstance<TDst>();
// a syntactical optimization
object src = source;
object dst = source;
if (destType.IsGenericType && destType.GetGenericTypeDefinition() == typeof(Nullable<>))
{
// get the underlying type
destType = Nullable.GetUnderlyingType(destType);
}
// trying to cast to nullable type from non-nullable type,
// or an implicit cast is required.
if (destType == typeof(int) && srcType == typeof(decimal))
dst = (int)(decimal)src;
if (destType == typeof(int) && srcType == typeof(double))
dst = (int)(double)src;
if (destType == typeof(int) && srcType == typeof(float))
dst = (int)(float)src;
if (destType == typeof(int) && srcType == typeof(short))
dst = (int)(short)src;
if (destType == typeof(int) && srcType == typeof(byte))
dst = (int)(byte)src;
if (destType == typeof(int) && srcType == typeof(int))
dst = (int)src;
// now try to cast it appropriately
try
{
result = (TDst)dst;
}
catch (Exception)
{
throw;
}
return result;
}
}
您将看到我正在执行双重隐式强制转换—第一次将类型打开,第二次将类型转换为目标类型。如果目标类型是可空的,它不会爆炸,因为它已经被强制转换为基类型。最后,如果没有指定自定义转换,它将尝试隐式强制转换,并可能弹出(有意的!)
授予-我并不是说你应该对所有的数据类型都这样做。但我不会告诉你如何编码,只是告诉你如何解决这个特殊的问题。这里的正确答案是匹配DTO对象的数据类型,只需写入