public class Animal {}
public class Cow: Animal {}
public class JerseyCow: Cow {}
Hello. So, I want to be able to pass a Subclass/Type as a parameter so that the method below works. After experimenting and researching, I can't find any that could make this work.
private double aveProf(Type xxxxxx)
{
double count = 0;
double sum = 0;
double ratio = 0;
foreach (KeyValuePair<int, Animal> animal in farmAnimalDict)
{
if (animal.Value.GetType() == typeof(xxxxxx))
{
sum = animal.Value.getProfit();
count ;
}
}
ratio = sum / count;
return ave;
}
So I want to be able to use it like this:
Console.WriteLine(aveProf(JerseyCow) aveProf(Cow));
CodePudding user response:
You need to use generics:
private double aveProf<TAnimal>()
where TAnimal: Animal // constrain it to only the Animal base class
// which is necessary to use .getProfit()
{
double count = 0;
double sum = 0;
double ratio = 0;
// using TAnimal and the dictionary's .Values property lets us
// simplify the loop and loop body
foreach (var animal in farmAnimalDict.Values.OfType<TAnimal>())
{
sum = animal.getProfit();
count ;
}
// I've assumed that the result should be 0 where there aren't
// any animals. This is to prevent a DivideByZeroException.
ratio = count > 0
? sum / count
: 0;
return ratio;
}
Usage:
double dogAvg = aveProf<Dog>();
double sheepAvg = aveProf<Sheep>();
double cowAvg = aveProf<Cow>();
You can use simplify it using LINQ too:
private double aveProf<TAnimal>()
where TAnimal: Animal
{
return farmAnimalDict.Values
.OfType<TAnimal>()
.Select(a => a.getProfit())
// if there are no animals of this type, we should default to 0
.DefaultIfEmpty(0)
.Average();
}
Usage:
double dogAvg = aveProf<Dog>();
double sheepAvg = aveProf<Sheep>();
double cowAvg = aveProf<Cow>();