2016-11-10 87 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方法