I'm creating an app that returns a list of metals to use in various conditions. I have a Metal class then classes for each type of Metal like Steel, Aluminum, etc. If I have a list of different Steels, I want to first select the best ones based on a set of properties common to all Metals then do a second pass based on the unique properties of Steel. (This isn't my exact problem but my problem is analogous.)
I can't figure out how to pass a List<Steel> to the GetBest() method of the Metal class as shown below that takes its first argument of type List<Metal>. The code won't compile due to error at the line highlighted below with **: "Argument 1: cannot convert from 'System.Collections.Generic.List<Steel>' to 'System.Collections.Generic.List<Metal>'.
public class Metal {
public int PropA { get; set; }
public List<Metal> GetBest( List<Metal> list, int condition1 )
{
var best = new List<Metal>();
//Analysis code here...
return best;
}
}
public class Steel : Metal
{
public int PropB { get; set; }
public List<Steel> GetBest(List<Steel> list, int condition1, int condition2 ) {
var bestSteel = new List<Steel>();
//Do first pass selection based on properties of all metals.
**bestSteel = Metal.GetBest(list, condition1);**
//Do some additional analysis based to Steel's unique properties.
//Analysis code here...
return bestSteel;
}
CodePudding user response:
You could use a constrained generic method:
public static List<T> GetBest<T>(List<T> list, int condition1) where T : Metal
{
var best = new List<T>();
// Analysis code here...
return best;
}
CodePudding user response:
I'm going to answer a different question! A look at how I might approach this problem without confounding my objects (Metal, Steel) with my logic for picking the best metal based on some conditions:
public class Metal{}
public class Steel:Metal{}
public class MetalPickerContext
{
public int Condition1{ get;set;}
}
public class MetalPicker<TMetal, TContext>
where TMetal: Metal
where TContext: MetalPickerContext
{
public virtual IEnumerable<TMetal> GetBest(IEnumerable<TMetal> list, TContext context)
{
var result = new List<TMetal>();
// logic for picking the best metal based on Condition1
return result;
}
}
public class SteelPickerContext: MetalPickerContext
{
public int Condition2{get;set;}
}
public class SteelPicker : MetalPicker<Steel,SteelPickerContext>
{
public override IEnumerable<Steel> GetBest(IEnumerable<Steel> list, SteelPickerContext context)
{
var initialResult = base.GetBest(list,context);
// Having called the base logic apply more with reference to Condition2
return initialResult;
}
}
This compiles (as you can see here) and I could expand the example a bit given some more details to make it a working one. Let me know if that would help you.
