使用子类作为参数

Using a Subclass to use as parameter

public class Animal {}
public class Cow: Animal {}
public class JerseyCow: Cow {}

您好。所以,我希望能够将 Subclass/Type 作为参数传递,以便下面的方法起作用。经过试验和研究,我找不到任何可以使这项工作成功的方法。

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;
        }

所以我希望能够像这样使用它:

Console.WriteLine(aveProf(JerseyCow) + aveProf(Cow));

您需要使用泛型:

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;
}

用法:

double dogAvg = aveProf<Dog>();
double sheepAvg = aveProf<Sheep>();
double cowAvg = aveProf<Cow>();

您也可以使用 LINQ 简化它:

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();
}

用法:

double dogAvg = aveProf<Dog>();
double sheepAvg = aveProf<Sheep>();
double cowAvg = aveProf<Cow>();