【问题标题】:C#, Generic Items list, with Specific Items in itC#,通用项目列表,其中包含特定项目
【发布时间】:2014-04-03 23:05:57
【问题描述】:

假设我有三个如下所示的类:

abstract class Fruit
{
     public string name { get; set; }
}

class Apple : Fruit
{
     public int redness { get; set; }
}

class Pear : Fruit
{
     public int size { get; set; }
}

我还有其他地方:

List<Fruit> delicious_things = new List<Fruit>{
      new Pear(){}
      new Apple(){}
}

我如何访问,例如delicious_things 中的pear.size?

如果我已经知道 Pear 是 nice_things[0],我可以这样做:delicious_things[0].size,但这似乎不起作用。

我错过了什么?提前致谢!

【问题讨论】:

  • 考虑围绕此类的接口和统一(或者,由于存在子类型,围绕基本类型)——我认为不同类型的水果可能都具有“颜色”和“大小”特征。跨度>

标签: c#


【解决方案1】:

为了访问特定的属性,您需要执行强制转换。此外,在执行强制转换时,您应该考虑使用 asis 运算符。因为如果您尝试从一种不兼容的类型执行强制转换(例如. 从ApplePear) 你会得到一个InvalidCastException:

var pear = delicious_things[0] as Pear;
int size;
if(pear != null) size = pear.size;

或者:

if(delicious_things[0] is Pear)
{
   int size = ((Pear)delicious_things[0]).size; 
}

【讨论】:

  • 如果你没有梨,这似乎是唯一不会爆炸的答案
  • @failedprogramming - 我认为这是因为问题问到If I know already that Pear is delicious_things[0]
  • @Oren 无论问题是如何提出的,都不会改变这个答案可以处理无梨情况的事实。虽然您的答案符合这个问题的参数,但我只是说我个人更喜欢这个,因为它可以实现更多。没有不尊重的意思。
  • @failedprogramming - 同意 - 对于初学者来说,了解 asis 运算符的使用可能更具教育意义。
【解决方案2】:

您必须将项目转换为特定类型。

((Pear)delicious_things[0]).size

但是,这不是好的设计。见Why should casting be avoided?

【讨论】:

  • 谢谢!作为后续:我能以某种方式在该列表中看到 [0] 的类型/类吗?
  • 您可以设置一个调试点并检查delicious_things,它将显示每个项目的具体类型。
  • 有没有不用调试的办法?
  • 您可能应该重新考虑您的设计。如果你一直在贬低你的物品......你做错了什么。代码不应该到处都是这样的演员表。
  • 使用GetType() 方法。尽管如前所述,如果您考虑这样做,您可能做错了。
【解决方案3】:

您可以对特定类型进行过滤:

delicious_things.OfType<Pear>().First().size;

这样,您确定它会在不投射对象的情况下获取第一个 Pear

当然,您仍然不确定列表是否包含至少一个 Pear 类型的元素

始终考虑所有可能性 --> 否则将来你会摔倒它

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-19
    • 1970-01-01
    • 2015-02-24
    • 1970-01-01
    • 1970-01-01
    • 2015-11-23
    • 2018-05-28
    相关资源
    最近更新 更多