【问题标题】:How to convert double to nullable int, int to nullable int in AutoMapper?如何在 AutoMapper 中将 double 转换为可为空的 int,将 int 转换为可为空的 int?
【发布时间】:2015-05-21 13:23:33
【问题描述】:

我不得不为此奋斗了一段时间。我使用 AutoMapper 在不同的数字格式之间进行映射,并且在将 int 映射到 int 时不断出错?等等。现在,我可以修改我的 DTO 对象以相应地匹配,但这并不容易。

我知道这主要是由于盒装类型和 AutoMapper 无关,但很高兴看到对类型转换的更多支持(例如强制隐式转换的标志,毕竟 AutoMapper 是一个辅助库)。

【问题讨论】:

    标签: c# .net automapper


    【解决方案1】:

    这里我们将使用自定义类型映射器:

    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 对象数据类型,只是说'

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-25
      • 1970-01-01
      • 2014-10-20
      • 2017-03-13
      • 1970-01-01
      • 2016-01-22
      • 2011-05-10
      相关资源
      最近更新 更多