2013-05-30 1 views
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이 뿌려줍니다. 내가 알고있는 유형의 변환 메소드 만 제대로 호출하기 때문에 널 참조가 가능하지 않다는 것을 알고있다. 캐스트 후에 null reference check를 던질 수는 있지만 불필요한 방어 프로그래밍이므로 가능한 한 깨끗하게 유지하려고합니다. 나는 또한 경고를 무시하고 계속 진행할 수 있다는 것을 알고 있지만 Resharper가 이것이 코드 냄새라고 말하고 있으며 올바른 방법을 알고 싶습니다.

이상한 세계에서는 다형성을 통해이를 수행하고 Base1에 ITranslatableToBase2 또는 이와 비슷한 인터페이스를 구현할 수 있습니다. 그러나 실제 코드에서 Base1은 POCO 라이브러리에서 제공되며 Base2를 인식하지 못하므로 번역기는 자체 다형성 객체 여야합니다. 나는 그것을 구현하려고 시도했는데, 팩토리 패턴을 사용하는 것이이 사전 패턴보다 약간 깔끔한 반면 캐스팅 문제는 여전히 존재한다.

그래서 여기에 생각의 실험으로 던지고 있습니다. 내가 생각할 수있는 모든 것을 다 써 버렸지 만, 내가 아직 생각하지 못했던 부분이있을 수 있습니다. 가능한 한 코드를 깨끗하게 유지하면서 무엇을 하려는지를 달성하는 가장 좋은 방법은 무엇입니까?

답변

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; } 
    } 
} 
+1

이것은 정말 멋집니다. ClassA에 ClassA 형식을 사용하고 거기에서 모든 번역 작업을 수행하는 생성자를 넣는 것이 더 간단한 대답 일 수 있다는 것을 알게됩니다. – user779860

관련 문제