我在C#中编程。我有一个抽象类(Animal)和两个从Animal继承的派生类(Dog和Cat)。我还有一个名为" Value"的静态方法。适用于Dog和Cat。但是,我的用户可能会调用此方法传递Animal。
如何确定它是狗还是猫? 我可以"标记"以某种方式上课? 如果我的设计错了,请告诉我,如果我做的是我不应该做的事情。
以下是一些示例代码。下面的最后一个函数(Value(Animal animal))是我不确定的函数。
public abstract class Animal
{
public Animal(string name)
{
Name = name;
}
public readonly string Name;
}
public class Dog : Animal
{
public Dog(string name, double weight)
: base(name)
{
Weight = weight;
}
public readonly double Weight;
}
public class Cat : Animal
{
public Cat(string name, bool old)
: base(name)
{
Old = old;
}
public readonly bool Old;
}
public class AnimalValuation
{
public static double Value(Dog dog)
{
return dog.Weight;
}
public static double Value(Cat cat)
{
if (cat.Old == true)
{
return 100.0;
}
else
{
return 0.0;
}
}
public static double Value(Animal animal)
{
// if animal is Dog then do something like:
Dog dog = (Dog)animal;
return Value(dog);
// if animal is Cat then do something like:
Cat cat = (Cat)animal;
return Value(cat);
}
}
答案 0 :(得分:2)
该运算符实际上是is
:
public static double Value(Animal animal)
{
if (animal is Dog) {
Dog dog = (Dog)animal;
return Value(dog);
}
if (animal is Cat) {
Cat cat = (Cat)animal;
return Value(cat);
}
}
另一种方法是使用抽象(虚拟)方法将值计算放在每个实现中:
public abstract class Animal {
public Animal(string name) {
Name = name;
}
public readonly string Name;
public abstract double Value();
}
public class Dog : Animal {
public Dog(string name, double weight) : base(name) {
Weight = weight;
}
public readonly double Weight;
public override double Value() {
return dog.Weight;
}
}
public class Cat : Animal
{
public Cat(string name, bool old) : base(name) {
Old = old;
}
public readonly bool Old;
public override double Value() {
if (Old) {
return 100.0;
} else {
return 0.0;
}
}
}
然后你不需要估价助手类,你可以使用:
double value = someAnimal.Value();
这种方法会强制您为您创建的任何新动物类实施Value
方法,因此您不必冒险忘记将其放入估价助手中。此外,任何人都可以在不需要更改估价助手的情况下实施新动物。
答案 1 :(得分:1)
你的方法是正确的,但我相信你应该在这里使用多态而不是静态Value
方法重载。
那么......为什么你不在Value
中声明一个抽象的Animal
属性,然后你就可以独立于Value
的实际具体类型访问Animal
(即Dog
或Cat
)?
public abstract class Animal
{
public Animal(string name)
{
Name = name;
}
public readonly string Name;
public abstract double Value { get; }
}
public class Dog : Animal
{
public Dog(string name, double weight)
: base(name)
{
Weight = weight;
}
public readonly double Weight;
public override double Value { get { return Weight; } }
}
public class Cat : Animal
{
public Cat(string name, bool old)
: base(name)
{
Old = old;
}
public readonly bool Old;
public override double Value { get { return Old ? 0 : 100; } }
}
现在它很容易。如果将Animal
派生的类对象引用作为其派生类进行输入,则可以访问Value
,并且您将获得没有静态的正确值和期望值:
Dog dog = new Dog("Bobby", 30);
Cat cat = new Cat("Kitty", false);
// We upcast Dog and Cat to Animal, but Value implementation
// is defined by the derived class, so even if you access
// Value from an Animal-typed reference, the Value will be
// the expected one for cats and dogs :)
Animal a1 = dog;
Animal a2 = cat;
double a1Value = a1.Value;
double A2Value = a2.Value;
正如@DarrenYoung在一些评论中所说,魔术数字是一个坏主意。由于Dog.Value
是权重而Cat.Value
是谁知道什么(0或100 ...),这可能导致混淆,使用类型为Animal
的引用的代码将无法知道Animal.Value
指的是什么......
Value
的实际含义。
答案 2 :(得分:0)
您编写的代码是(或至少'a')确定给定对象的派生类型最多的正确方法。
然而,我建议您的代码设计可能会引起一些注意。我不知道'Value'方法在您的生产应用程序中扮演什么角色,但我认为它应该是Animal
类型的成员,并被Dog
覆盖,Cat
等...
答案 3 :(得分:0)
if(animal.GetType() == typeof(Dog))
或
if(animal is Dog)