需要通用c#方法的解决方案
本文关键字:方法 解决方案 | 更新日期: 2023-09-27 18:17:17
我正试图使我的方法通用,我被困在一个点,需要你的帮助。代码场景是,我有一个抽象类,比如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; }
}
现在我必须创建一个公共方法,它需要在Mychild1
和Mychild2
的基础上执行一些操作,所以我所做的是:
public MyCustomClass SaveOperation<T>(T myObj)
where T : MyBaseAbs
{
SaveObject obj = new SaveObject();
}
所以在这个方法中,我需要编写公共代码,根据传递的子对象为SaveObject
对象进行映射。如何确定传递的对象并使用相应的属性
一种选择是在基类中创建一个基本的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
}
}
如果不能修改业务对象,可以在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语句中添加另一个分支。
正如@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
方法
你可以这样使用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