如何编写转换器类?如何有效地编写映射规则?

Mar*_*tus 6 c# architecture mapping design-patterns converter

我有一个很大的A级,有很多成员,我有一个很大的B级,可以在拥有一个A对象时构建.具有B对象时可以构建A对象.我需要它们两个,因为A是一种ViewModel,它有验证,B是图形描述,可以很容易地绘制.

怎么做这个转换?

这是一个例子,来说明我想做的事情:

class A
{
    string s;
    string t;
    string u;
    string v;

    enum a;
    enum b;
    enum c;
    enum d;
    enum e;

    Dictionary<enum, string> dict;
}


class B
{
    string someString; // is essentially A.a + A.b + A.c + A.s with some rules.
    int someValue; // is essentially dict.TryGetValue(enum.Entry);
    string anotherString;
    // ... and lots of others
}
Run Code Online (Sandbox Code Playgroud)

当然,做一些映射很简单,并且构建一个B对象,通过反转构建A => B的规则来编写普通的B => A映射并不是很难.

所以问题是:

  • 是否有任何众所周知的模式来实现这一目标?
  • 是否有默认的C#方式来做这些事情?

写下类似的东西似乎不合适,最终会产生数百行代码.

我想到了某些部件的转换器类,比如SomeStringConverter,SomeValueConverter,......

  • 我如何抽象所需的A成员和规则来进行映射.
  • 如何编写这些规则以便以最简单的方式进行A => B和B => A.

编辑: 这里的模式是"最佳实践",而不是"GoF设计模式"

B类中的SomeString是某种"选择器",它选择绘图选项,它总是25个字符长,A类中的枚举选择那些字符,但在大多数情况下不是1对1.

让我们举例说:Aa ="Filled",Ab ="SingleCoordinate",Ac ="DrawHints"会产生像SomeString =

 "Y**D***RR****---***---***"
Run Code Online (Sandbox Code Playgroud)

即组合对于获得这样的字符串很重要,但是从组合中可以派生出必须在A对象中设置的枚举.

EDIT2:

我对两种方式使用我的映射规则的方式特别感兴趣,即Aa ="Filled"结合Ab ="SingleCoordinate"与Ac ="DrawHints"组合将导致(部分字符串)"Y**D***RR",并且该部分字符串也意味着Aa必须设置为"填充"等等.

Mar*_*tus 0

我为解决这个问题所做的事情:

  1. 写了一个 BiMap(在老 SO 的帮助下解决了这个问题)。

  2. 将映射插入其中(Key 中的所有值组合、“Value”中的结果键,以及指定由该映射定义的字符串索引的 BitArray。

  3. 编写了一些代码来计算由此产生的整个字符串,因为映射只会给出部分字符串。

  4. 一对一的映射是微不足道的。

这样我就可以以两种方式使用映射。给定一个字符串,我仍然需要进行相当昂贵的搜索(因为我必须利用 BitArray 作为掩码来计算存储的字符串)

目前看来效果很好,但我还没有完成。

感谢大家的好想法和方法!也许AutoMapper可以做到这一点,但我目前没有太多时间来阅读和尝试新技术。

如果有人可以提供一些有关如何在 Automapper 上执行此操作的相关示例,我将接受它作为答案(因为我已经喜欢 AutoMapper)。

例如,可以这样说: 3 个具有 5 个值的枚举到一个固定长度字符串 一个固定长度字符串到 3 个具有 5 个值的枚举(与上述相反)。

举个例子:

A.a && B.o && C.y ==> "**A**********************"
A.a && B.p && C.y ==> "**B**********************"
A.b && B.o && C.y ==> "*****X*******************"
A.b && B.o && C.z ==> "*****W*******************"
Run Code Online (Sandbox Code Playgroud)

Automapper能做到这样的事情吗?