2016-11-10 90 views
0

我想使我的方法通用,我卡在一個點,需要您的幫助。該代碼的情況是我有一個抽象類,說MyBaseAbs其中包含常用的屬性:需要有關通用C#方法的解決方案

public abstract class MyBaseAbs 
{ 
    public string CommonProp1 { get; set; } 
    public string CommonProp2 { get; set; } 
    public string CommonProp3 { get; set; } 
} 

現在我有子類:

public class Mychild1: MyBaseAbs 
{ 
    public string Mychild1Prop1 { get; set; } 
    public string Mychild1Prop2 { get; set; } 
    public string Mychild1Prop3 { get; set; } 
} 

和另一子類:

public class Mychild2: MyBaseAbs 
{ 
    public string Mychild1Prop1 { get; set; } 
    public string Mychild2Prop2 { get; set; } 
} 

現在我必須根據Mychild1Mychild2創建一個需要執行某些操作的常用方法,所以我所做的是:

public MyCustomClass SaveOperation<T>(T myObj) 
     where T : MyBaseAbs 
{ 
    SaveObject obj = new SaveObject(); 

} 

所以這種方法內我需要編寫通用代碼根據傳遞的子對象它執行映射SaveObject對象。我怎樣才能確定哪個對象被傳遞並相應地使用屬性。

+0

沒有關於SaveOperation方法的足夠信息。一個明顯的解決方案是如何檢查類型。 'if(myObj is Mychild1)' –

+1

如果你的代碼需要爲不同的子類做不同的事情,爲什麼要使它成爲通用的?爲每個具體子類寫一個'SaveOperation',並且(如果需要的話)有一個基於具有公共代碼並且每個具體方法可以調用的基類的私人'SaveOperation'。 –

+0

SaveOperation是什麼類? – Enigmativity

回答

5

一種選擇是在你的基類來創建一個基本Save功能,並使其虛擬化。

然後覆蓋您的子類中的方法。通過這種方式,當您在SaveOperation中調用Save方法時,它應該從正確的子類中調用適當的方法。

public abstract class MyBaseAbs 
{ 
    public string CommonProp1 { get; set; } 
    public string CommonProp2 { get; set; } 
    public string CommonProp3 { get; set; } 

    public virtual void Save() { } 
} 

public class Mychild1: MyBaseAbs 
{ 
    public string Mychild1Prop1 { get; set; } 
    public string Mychild1Prop2 { get; set; } 
    public string Mychild1Prop3 { get; set; } 

    public override void Save() { 
     //Implementation for Mychild1 
    } 
} 

public class Mychild2: MyBaseAbs 
{ 
    public string Mychild1Prop1 { get; set; } 
    public string Mychild2Prop2 { get; set; } 

    public override void Save() { 
     //Implementation for Mychild2 
    } 
} 
+0

感謝Bojan的迴應,但我可以在業務對象內創建方法。 –

+0

@SanjayBathre對不起,我不太理解你的評論。你的情況是什麼商業對象? –

+0

我提到的類是那些。 –

2

如果你不能修改你的業務對象,你可以檢查具體類的在SaveOperation方法類型:

public MyCustomClass SaveOperation<T>(T myObj) 
     where T : MyBaseAbs 
{ 
    SaveObject obj = new SaveObject(); 

    if (myObj is Mychild1) { 
     Mychild1 mychild1 = (Mychild1) myObj; 

     // Business logic for object of type Mychild1 

    } else if (myObje is Mychild2) { 
     Mychild2 mychild2 = (Mychild2) myObj; 

     // Business logic for object of type Mychild2 

    } 

} 

請注意,這並不是一個非常堅實的解決方案,如果你正在創建實現你的抽象類的新對象,你將不得不記住在if語句中添加另一個分支。

2

正如@BojanB提到的,顯而易見的解決方案是在您的基類中創建一個虛擬方法,並在派生類中重寫它,但是如果您不能修改那裏的代碼,那麼您可以爲每個派生類創建一個方法並創建每一種類型映射到其方法的字典:

private Dictionary<Type, Action<MyBaseAbs, MyCustomClass>> _saveOperations = 
          new Dictionary<Type, Action<MyBaseAbs, MyCustomClass>>(); 

//You can then set an entry for each of your derived classes 
_saveOperations[typeof(Mychild1)] = (myObj, myCustomObj) => 
{ 
    //Mychild1-specific logic 
}; 

public MyCustomClass SaveOperation(MyBaseAbs obj) 
{ 
    //do the common saving operations here 
    var result = new MyCustomClass(); 
    //.... 

    var actualType = obj.GetType(); 
    if(_saveOperations.ContainsKey(actualType)) 
    { 
     _saveOperations[actualType](obj, result); 
    } 

    return result; 
} 

然後,您可以將項目添加到字典中的每個派生類。它與使用is運算符的概念相同,但允許您在不修改原始方法的情況下添加更多派生類型的方法。SaveOperation方法