我想是一个基本问题,但如果我想让一个对象拥有另一个类型为A或B的对象,那么使用该对象的应用程序如何访问特定属性? E.g。
public abstract class Animal
{
private int Age;
// Get Set
}
public class Tiger: Animal
{
private int NoStripes;
// Get Set
}
public class Lion : Animal
{
private bool HasMane;
// Get Set
}
public class Zoo
{
private Animal animal;
// Get Set
}
public static void Main()
{
Zoo zoo = new Zoo();
zoo.animal = new Tiger();
// want to set Tiger.NoStripes
}
答案 0 :(得分:2)
您必须将zoo.Animal
投射到Tiger
或者您可以尝试类似
的内容public abstract class Animal
{
public int Age;
// Get Set
}
public class Tiger : Animal
{
public int NoStripes;
// Get Set
}
public class Lion : Animal
{
public bool HasMane;
// Get Set
}
public class Zoo<T> where T : Animal
{
public T animal;
// Get Set
}
Zoo<Tiger> zoo = new Zoo<Tiger>();
zoo.animal = new Tiger();
zoo.animal.NoStripes = 1;
答案 1 :(得分:0)
直接的答案是
public static void Main() {
Zoo zoo = new Zoo();
zoo.animal = new Tiger();
((Tiger)zoo.Animal).NoStripes = 10;
}
当然,为了实现这一目标,您需要知道zoo.Animal
实际上是Tiger
。您可以使用zoo.Animal is Tiger
对其进行测试(尽管as
运算符优先于is
)。
但是,一般情况下,设计这样的程序并不是很好。您必须编写的代码很可能很麻烦。
答案 2 :(得分:0)
这是继承和多态的要点。
如果您能够确定Animal的实例实际上是Tiger的一个实例,您可以投射它:
((Tiger)zoo.Animal).NoStripes = 1;
但是,如果您尝试在不是Tiger的Animal实例上执行此操作,您将获得运行时异常。
例如:
Zoo zoo = new Zoo();
zoo.animal = new Tiger();
((Tiger)zoo.Animal).NoStripes = 1; //Works Fine
((Lion)zoo.Animal).NoStripes = 1; //!Boom - The compiler allows this, but at runtime it will fail.
有一种替代的转换语法,使用“as”关键字,如果转换失败,则返回null,而不是异常。这听起来很棒,但实际上,当null对象被消耗时,你可能会在以后遇到细微的错误。
Tiger temp = zoo.Animal as Tiger; //This will not throw an exception
temp.NoStripes = 1; //This however, could throw a null reference exception - harder to debug
zoo.Animal = temp;
要避免空引用异常,您可以对课程进行空检查
Tiger temp = zoo.Animal as Tiger; //This will not throw an exception
if (temp != null)
{
temp.NoStripes = 1; //This however, could throw a null reference exception - harder to debug
zoo.Animal = temp;
}