Home > Net >  Using a Subclass to use as parameter
Using a Subclass to use as parameter

Time:04-16

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>();
  • Related