在我的代碼中,我有一些對象的集合,這些對象是不適用於新代碼的類的實例。他們都需要翻譯成本地定義的相應類。我試圖做一個乾淨的方式來確定實例所屬的類的類型,並根據該類型調用適當的翻譯方法。但是,我似乎無法找到像我想的那樣乾淨利落的方法。這是我的代碼。有沒有更好的方法來選擇基於類類型的翻譯方法?
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,所以翻譯器必須是它自己的多態對象。我試着實現它,事實證明,雖然使用工廠模式比我在這裏的字典模式稍微清潔,但鑄造問題仍然存在。
所以,我把它作爲一個思想實驗扔在這裏。我用盡了幾乎所有我能想到的東西,但也許還有一些我還沒有想到的東西。在保持代碼儘可能清潔的同時,實現我想要做的事情的絕對最佳方式是什麼?
這看起來很酷。它讓我意識到,可能有一個更簡單的答案,就是隻需在ClassC中放入一個構造函數,該類就會接受一種ClassA並在那裏進行所有翻譯工作。 – user779860