访问抽象对象的具体属性?

发布于 2024-10-08 22:00:08 字数 509 浏览 7 评论 0原文

我猜这是一个基本问题,但如果我希望一个对象拥有另一个类型为 A 或 B 的对象,那么使用该对象的应用程序如何访问特定属性?例如

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
}

Bit of a basic question I guess, but if I want an object to own another object of type either A or B, how can the application using the object access the specific attributes? 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
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

本宫微胖 2024-10-15 22:00:08

您必须将 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;

You will have to cast zoo.Animal to Tiger

Or you could try something like

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;
来世叙缘 2024-10-15 22:00:08

这就是继承和多态性的要点。

如果您能够确定 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,而不是异常。这听起来不错,但实际上,当空对象被消耗时,您可能会在稍后遇到微妙的错误。

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

This is the gist of inheritance and polymorphism.

If you are able to determine that an instance of Animal is in fact an instance of Tiger, you can cast it:

((Tiger)zoo.Animal).NoStripes = 1;

However, if you try do do this on an instance of Animal that isn't a Tiger, you'll get a runtime exception.

for example:

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.

There is an alternative casting syntax that using the "as" keyword, which returns null, instead of an exception if the cast fails. This sounds great, but in practice you're likely to get subtle bugs later on when the null object gets consumed.

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;

To avoid the null reference exception, you can null check of course

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;
}
白色秋天 2024-10-15 22:00:08

直接的答案是:

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 更可取)。

然而,一般来说,像这样设计你的程序听起来不太好。您必须编写的代码可能会很麻烦。

The direct answer is to do

public static void Main() {
    Zoo zoo = new Zoo();
    zoo.animal = new Tiger();

    ((Tiger)zoo.Animal).NoStripes = 10;
}

Of course for this to work you need to know that zoo.Animal is in fact a Tiger. You can use zoo.Animal is Tiger to test for that (although the as operator is preferable vs. is).

In general, however, designing your program like this doesn't smell very nice. It's probable that the code you will have to write will be cumbersome.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文