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 は翻訳メソッド (「as」キーワードの後) で NullReferenceException の可能性について不平を言います。適切にキャストされることがわかっている型でのみ変換メソッドを呼び出しているため、null 参照が不可能であることはわかっています。キャストの後に null 参照チェックを入れることもできますが、それは不必要な防御的プログラミングであり、これをできるだけきれいに保とうとしています。また、警告を無視して続行できることも知っていますが、Resharper がこれはコードの匂いだと言っていることも認識しており、それを行う適切な方法を知りたいと思っています。

理想的な世界では、ポリモーフィズムを通じてこれを行い、Base1 に ITranslatableToBase2 などと呼ばれるインターフェイスを実装させることができます。しかし、私の実際のコードでは、Base1 は POCO ライブラリに由来し、Base2 を認識していないため、トランスレータは独自のポリモーフィック オブジェクトである必要があります。私はそれを実装してみましたが、ファクトリ パターンを使用することは、ここにあるこの辞書パターンよりもわずかにきれいですが、キャストの問題がまだ存在することがわかりました。

ですから、思考実験としてここに投げ出します。考えられることはほとんど尽きましたが、まだ考えていないことがあるかもしれません。コードをできるだけきれいに保ちながら、私がやろうとしていることを達成するための絶対的な最良の方法は何ですか?

4

1 に答える 1