0

在我的代码中,我有一个对象集合,这些对象是不适用于新代码的类的实例。它们都需要翻译成本地定义的相应类。我正在尝试以一种简洁的方式来确定实例的类类型并根据该类型调用适当的翻译方法。但是,我似乎无法找到一种方法来像我想要的那样干净地做到这一点。这是我的代码。

using System;
using System.Collections.Generic;
using System.Linq;

namespace TranslatorSwitchExample
{
    public class Class1
    {
        void DoWork()
        {
            var oldTypes = new Base1[]
                {
                    new ClassA{ IntProperty = 1 },
                    new ClassB{ StringProperty = "test" }, 
                };
            var newTypes = TranslateAll(oldTypes);
        }

        static IEnumerable<Base2> TranslateAll(IEnumerable<Base1> oldTypes)
        {
            var newTypes = oldTypes.Select(x => TranslateByType[x.GetType()](x));
            return newTypes;
        }

        static readonly Dictionary<Type, Func<Base1, Base2>> TranslateByType =
            new Dictionary<Type, Func<Base1, Base2>>
                {
                    { typeof(ClassA), TranslateClassAToClassC },
                    { typeof(ClassB), TranslateClassBToClassD }
                };

        static Base2 TranslateClassAToClassC(Base1 old)
        {
            var oldClassA = old as ClassA;
            return new ClassC
                {
                    IntProperty = oldClassA.IntProperty
                };
        }

        static Base2 TranslateClassBToClassD(Base1 old)
        {
            var oldClassB = old as ClassB;
            return new ClassD
                {
                    StringProperty = oldClassB.StringProperty
                };
        }
    }

    abstract class Base1 { }

    class ClassA : Base1
    {
        public int IntProperty;
    }

    class ClassB : Base1
    {
        public string StringProperty;
    }

    abstract class Base2 { }

    class ClassC : Base2
    {
        public int IntProperty;
    }

    class ClassD : Base2
    {
        public string StringProperty;
    }
}

这可以完成我想要的一切,但是 Resharper 抱怨我的翻译方法中可能出现的 NullReferenceException (在“as”关键字之后)。我知道空引用是不可能的,因为我只使用我知道可以正确转换的类型调用翻译方法。我可以在演员表之后进行空引用检查,但这是不必要的防御性编程,我正在努力保持它尽可能干净。我也知道我可以忽略警告并继续前进,但我也认识到 Resharper 告诉我这是代码异味,我想知道正确的方法。

在一个理想的世界里,我可以通过多态来做到这一点,并让 Base1 实现一个名为 ITranslatableToBase2 的接口或类似的东西。但是在我的实际代码中,Base1 来自 POCO 库并且不知道 Base2,因此翻译器必须是它​​自己的多态对象。我尝试实现它,结果发现虽然使用工厂模式比我在这里使用的字典模式稍微干净一些,但转换问题仍然存在。

所以,我把它作为一个思想实验扔在这里。我已经用尽了我能想到的几乎所有东西,但也许还有一些我还没有想到的东西。在保持代码尽可能干净的同时实现我想要做的事情的绝对最佳方法是什么?

4

1 回答 1

2

也许您可以使用适配器模式;你可以有一个 IClassC 的接口,ClassC 会实现这个,然后:

public class ClassBToCAdapter : IClassC
{
     private ClassB adaptee;
     public ClassBToCAdapter(ClassB classB)
     {
        this.adaptee = classB
     }

     public int IntProperty
     {
        get { return adaptee.IntProperty; }
        set { adaptee.IntProperty = value; }
     }
}
于 2013-05-30T20:41:31.340 回答