c# - ExpressMapper - 映射/克隆枚举 - InvalidCastException

标签 c# enums

我目前在使用 EmitMapper 的解决方案中遇到性能问题。由于性能和积极维护的事实,我想将我的 IMapper 的实现更改为 ExpressMapper。

我的问题归结为映射枚举以及不应直接转换枚举的事实,因为这会生成 InvalidCastException。

该解决方案本质上是非常通用和动态的,我的主要 ExpressMapper 实现包含以下方法:

public TDestination Map<TSource, TDestination>(TSource src)
{
    return src.Map<TSource, TDestination>();
}

在不同的命名空间中有 2 个相同的 Customer 类,如下所示:

public class Customer
{
    public string Name { get; set; }

    public CustomerType Type { get; set; }
}

public enum CustomerType
{
    Company,
    Private,
    Government
}

我创建了一个简单的 MSTest:

[TestClass]
public class ExpressMapperTest
{
    [TestMethod]
    public void SimpleMap()
    {
        // Arrange
        var myMapper = new MyMapper();
        Mappings.Source.Customer sourceCustomer = new Mappings.Source.Customer {
            Name = "John Doe",
            Type = Mappings.Source.CustomerType.Company
        };

        // Act
        var targetCustomer = myMapper.Map<Mappings.Source.Customer, Mappings.Target.Customer>(sourceCustomer);

        // Assert
        Assert.AreEqual(sourceCustomer.Name, targetCustomer.Name);
        Assert.AreEqual((int)sourceCustomer.Type, (int)targetCustomer.Type);
    }

}

结果是:

Test method ExpressMapperTest.ExpressMapperTest.SimpleMap threw exception: System.InvalidCastException: Invalid cast from 'Mappings.Source.CustomerType' to 'Mappings.Target.CustomerType'.

at System.Convert.DefaultToType(IConvertible value, Type targetType, IFormatProvider provider) at System.Enum.System.IConvertible.ToType(Type type, IFormatProvider provider) at System.Convert.ChangeType(Object value, Type conversionType, IFormatProvider provider) at System.Convert.ChangeType(Object value, Type conversionType) at lambda_method(Closure , Customer , Customer ) at ExpressMapper.TypeMapperBase`2.MapTo(T src, TN dest) in C:\SourceCode\ExpressMapper\ExpressMapper NET40\TypeMapperBase.cs:line 243 at ExpressMapper.MappingServiceProvider.MapInternal[T,TN](T src, TN dest, Boolean dynamicTrial) in C:\SourceCode\ExpressMapper\ExpressMapper NET40\MappingServiceProvider.cs:line 273 at ExpressMapper.MappingServiceProvider.MapInternal[T,TN](T src, TN dest, Boolean dynamicTrial) in C:\SourceCode\ExpressMapper\ExpressMapper NET40\MappingServiceProvider.cs:line 299 at ExpressMapper.MappingServiceProvider.Map[T,TN](T src) in C:\SourceCode\ExpressMapper\ExpressMapper NET40\MappingServiceProvider.cs:line 241 at ExpressMapper.Mapper.Map[T,TN](T src) in C:\SourceCode\ExpressMapper\ExpressMapper NET40\Mapper.cs:line 38
at ExpressMapper.Extensions.ExpressmapperExtensions.Map[T,TN](T source) in C:\SourceCode\ExpressMapper\ExpressMapper NET40\ExpressmapperExtensions.cs:line 11

任何直接使用 CustomerType 枚举类型的解决方案都是无效的,因为它是一个由可插入组件组成的动态系统,每个组件都有自己的要映射的对象图,例如从 CustomerProxy 到 Customer 组件(域对象)。

我尝试了很多方法,包括实现 CustomMapper 以通用方式映射枚举,但我没有中奖。 - 我想知道是否唯一的出路是改变 ExpressMapper 本身。

上述标准枚举之间映射的正确方法是: Mappings.Source.CustomerType -> int -> Mappings.Target.CustomerType

....不会抛出 InvalidCast。

最佳答案

Expressmapper 通过使用 IConvertible 接口(interface)支持隐式转换,这里不是这种情况。我创建了 Github issue只是考虑它是否是实现的有效案例。 到目前为止,您有很多选择,但最简单和最快的是:

Mapper.Register<Mappings.Source.Customer, Mappings.Target.Customer>()
   .Member(dst => dst.Type, src => (Mappings.Target.CustomerType)((int)src.Type));

在上面注册后,只需使用您的客户端映射代码。 感谢您的宝贵意见!

更新:Expressmapper 1.8 通过使用整数值作为枚举的映射标准来支持枚举映射。

关于c# - ExpressMapper - 映射/克隆枚举 - InvalidCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34075459/

相关文章:

c# - 单声道:运行时错误:v4.0.30319

c# - 比较两个列表并将匹配列保存到单独的列表

java - 当字符串包含破折号时打开枚举

c# - 如何正确地对异步套接字连接操作进行单元测试并避免 Thread.Sleep?

c# - 在线 Exe 生成器

c# - 如何将文件添加到现有的 zip 存档

MySQL 5 星评级数据类型?

java - Groovy 枚举中的计算值

python - django 将枚举中的项目翻译成其他语言

c - 迭代地为 C 结构赋值