我不得不与此争吵一段时间。我使用AutoMapper在不同的数字格式之间进行映射,并在将int映射到int时不断出错?现在,我可以相应地修改我的DTO对象,但它并不那么容易。
我理解这主要是由于盒装类型而与AutoMapper无关,但很高兴看到更多支持类型转换(例如在所有AutoMapper都是辅助库之后强制隐式转换的标志)。 / p>
答案 0 :(得分:2)
这里我们将使用自定义类型映射器:
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对象数据类型,只需说&#39;