Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/297.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 具有复杂逻辑的对象到对象转换_C#_.net_Design Patterns - Fatal编程技术网

C# 具有复杂逻辑的对象到对象转换

C# 具有复杂逻辑的对象到对象转换,c#,.net,design-patterns,C#,.net,Design Patterns,假设我们有一些复杂类Foo的对象和一些branchy类型的层次结构,例如: class Bar {} class BarA:Bar{} class BarB:Bar{} class BarC:BarA{} 任务是将Foo对象转换为Bar子体之一。我们有两套规则: 根据Foo字段值,我们应该选择哪些Bar后代的规则。例如,如果foo.Type==“A”和foo.Complex==true则foo应转换为BarC对象 有关如何将foo字段转换为BarXXX字段的规则。例如,如果我们选择BarA作

假设我们有一些复杂类
Foo
的对象和一些branchy类型的层次结构,例如:

class Bar {}
class BarA:Bar{}
class BarB:Bar{}
class BarC:BarA{}
任务是将Foo对象转换为Bar子体之一。我们有两套规则:

  • 根据
    Foo
    字段值,我们应该选择哪些
    Bar
    后代的规则。例如,如果
    foo.Type==“A”
    foo.Complex==true
    foo
    应转换为
    BarC
    对象
  • 有关如何将
    foo
    字段转换为
    BarXXX
    字段的规则。例如,如果我们选择
    BarA
    作为目标类,那么
    foo.Date
    应该转换为
    BarA.DateA
    。但是如果我们选择
    BarC
    foo.Date
    应该转换为
    BarC.DateC
    BarC.DateA
    应该是
    DateTime.MinValue
我只是想避免重新发明轮子,用条件逻辑的音调编写spagetti代码。我认为AutoMapper和ValueInjector在这里帮不了忙。
我在寻找一些优雅的解决方案。有什么建议吗?

没有必要使用高级模式:一个简单的元组列表
{predicate,builder}
就足以满足您的需求

创建一个IList类型的列表,并向其中添加成对的“checker”和“maker”,如下所示:

private static readonly IList<Tuple<Predicate<Foo>,Func<Foo,Bar>>> CheckersAndMakers =
    new List<Tuple<Predicate<Foo>,Func<Foo,Bar>>>()
{
    new Tuple<Predicate<Foo>,Func<Foo,Bar>>(
        f => f.Type == "A" && f.Complex  // Checker
    ,   f => new BarC {DateC = foo.Date} // Maker
    )
,   new Tuple<Predicate<Foo>,Func<Foo,Bar>>(
        f => f.Type == "C" && !f.Complex  // Checker
    ,   f => new BarA {DateA = DateTime.MinValue} // Maker
    )
};

在不提供所有条件的情况下,我们如何才能在这些条件中找到一些技巧或模式,让您做一些事情,而不仅仅是检查所有条件?问题不是要避免检查条件,而是要找到一些通用方法。无论条件是什么,都没有通用的案例解决方案。如果我们知道条件是什么,有可能,对于那些条件,有其他的方法可以做到。是的,谢谢。这是一种策略模式,我把它作为紧急出口:)@Alina我不会用“模式”的名字来美化这个简单的把戏:本质上,两个并行的函数指针列表使它变得尽可能灵活,并将所有映射逻辑放在一个地方。
Bar MakeFromFoo(Foo f) {
    foreach (var tuple in CheckersAndMakers) {
        if (tuple.Item1(f)) {
            return tuple.Item2(f);
        }
    }
    throw new ApplicationError("Unrecognized foo");
}