I have a method that is overloaded 3 times with the exact same functionality, the only change is one parameter which is a list of a concrete type.
private void _doWork(string name, List<TargetItem> members)
{
foreach(var member in members)
{
_doExtraWork(member.TimeToWork);
}
}
private void _doWork(string name, List<NonTargetItem> members)
{
foreach(var member in members)
{
_doExtraWork(member.TimeToWork);
}
}
Thing to know here is the 2 classes in the lists are coming from a WSDL definition. The operation in the iteration is on shared members as they derive from the same base class, however this inheritance is abstracted in the WSDL.
I have tried to do something like this -
private void _doWork<T>(string name, List<T> members)
{
var commonList = new List<>(); /// what type should I use here?
if(typeof (T) == typeof(TargetItem))
{
commonList = members; // assume equal to means copying members to commonList with type conversion
}
if(typeof (T) == typeof(NonTargetItem))
{
commonList = members;
}
foreach(var member in commonList)
{
_doExtraWork(member.TimeToWork);
}
}
Is this the right way to approach the problem and refactor this common code, or am I missing something here?
you can do something like this
private static void _doWork<T>(string name, T members) where T : IEnumerable
{
foreach(var member in members)
{
_doExtraWork(member.TimeToWork);
}
}
In your Calling Code
_doWork("sdfsd", new List<TargetItem>()); // here just as example I am passing new instance
_doWork("sdfsd", new List<NonTargetItem>()); // here just as example I am passing new instance
As the List<T>
is of type IEnumerable<T>
which in turn is of type IEnumerable. You can add IEnumerable generic constaints in your generic functions. In this way, you do not have to do type checking in your generic functions.
If you want to implement single doExtraWork method then you need to have CommonType for both TargetItem and NonTargetItem. you can solve this using Adapter Pattern like below
Interface IItem
{
int TimeToWorkAdapt {get;}
}
//Now create a wrapper class for TargetItem and NonTargetItem
Class TargetItemAdapt : TargetItem,IItem
{
public int TimeToWorkAdapt
{
get { base.TimeToWork;}
}
}
Class NonTargetItemAdapt : NonTargetItem,IItem
{
public int TimeToWorkAdapt
{
get { base.TimeToWork;}
}
}
// write a generic function which wrap calls to your do extra work method but with generic constriants to interface
private static void _doExtraWork<T>(T members) where T : IItem
{
_doExtraWork(member.TimeToWorkAdapt);
}
// In your Main program...now use our wrapper classes
_doWork("sdfsd", new List<TargetItemAdapt>()); // here just as example I am passing new instance
_doWork("sdfsd", new List<NonTargetItemAdapt>()); // here just as example I am passing new instance
I chose to downcast from the caller
_doWork("Target", Object.TargetItems.ToList<BaseClass>());
_doWork("NonTarget", Object.NonTargetItems.ToList<BaseClass>());
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.