2013-05-30 21 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異常(以下簡稱「爲」關鍵字後)。我知道一個空引用是不可能的,因爲我只用我知道會正確轉換的類型調用翻譯方法。在演員陣容後我可以投入空引用檢查,但這是不必要的防守編程,我試圖儘可能保持乾淨。我也知道,我可以忽略警告並繼續前進,但我也認識到,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

這看起來很酷。它讓我意識到,可能有一個更簡單的答案,就是隻需在ClassC中放入一個構造函數,該類就會接受一種ClassA並在那裏進行所有翻譯工作。 – user779860

相關問題