需要关于通用c#方法的解决方案

时间:2016-11-10 06:58:39

标签: c#

我正在努力让我的方法变得通用,而我却陷入困境,需要你的帮助。代码场景是我有一个抽象类,说MyBaseAbs,它包含公共属性:

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对象的映射。如何确定传递的对象并相应地使用属性。

4 个答案:

答案 0 :(得分:5)

一种选择是在基类中创建基本Save函数并使其成为虚拟函数。

然后覆盖子类中的方法。这样,当您在Save中调用SaveOperation方法时,它应该从正确的子类调用适当的方法。

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
    }
}

答案 1 :(得分: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 :(得分: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方法的情况下为更多派生类型添加方法

答案 3 :(得分:1)

您可以按如下方式使用C#的As-Operator:

Mychild1 child1 = myObj as Mychild1;
if(child1 != null) {
   //Here you can use child1.Mychild1Prop1 forexample
}

链接到msdn:https://msdn.microsoft.com/en-us/library/cscsdfbt.aspx