C# 包含继承类的基类数组,访问非继承字段

Posted

技术标签:

【中文标题】C# 包含继承类的基类数组,访问非继承字段【英文标题】:C# array of base class containing inherited classes, accessing non-inherited fields 【发布时间】:2019-05-14 08:06:06 【问题描述】:

我有一个抽象类 Detail,以及扩展 Detail 的四个类 Rock、Grass、Tree 和 Bush。

Tree 和 Bush 有 Fruit 属性,但其他没有

我有一个 Detail[],其中包含所有 4 种类型的细节,并且给定一个索引,我需要找到该细节的果实,如果有的话。

我不想将 Fruit 属性放在基类 Detail 中,因为并非所有细节都有水果,而且不同种类的细节具有完全不同的属性。

如何在不知道它是什么类型的细节或它是否有结果的情况下获得例如 Detail[17] 的果实(如果没有,可能返回 null)?请记住,可能会有数百种不同类型的细节以及数十种可能的属性。

我正在想象某种标记系统,其中数组中的每个项目可能有也可能没有几个标签中的一个,但这是我迄今为止管理过的最接近的一个。

【问题讨论】:

【参考方案1】:

使TreeBush 以及其他具有Fruit 属性的子类实现IHasFruit,如下所示:

interface IHasFruit 
    // I assume "Fruit" properties are of type "Fruit"?
    // Change the type to whatever type you use
    Fruit Fruit  get; 


class Tree : Detail, IHasFruit 
    ...


class Bush : Detail, IHasFruit 
    ...

现在,您可以编写一个GetFruit 方法:

public Fruit GetFruit(int index) 
    Detail detail = details[index];
    return (detail as IHasFruit)?.Fruit; // this will return null if the detail has no fruit.

【讨论】:

【参考方案2】:

你也可以拥有 IHasFruit 接口,以及提供水果的类,然后你可以通过你的接口循环。

IHasFruit [] myArray

或者如果你需要使用

Detail[] myArray
foreach (var item in myArray)

     If (item  is IHasFruit hasFruit)
         //do whatever

或带反射(较慢)

Detail[] myArray
foreach (var item in myArray)

     var hasFruit= item.GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IHasFruit<>));

或者,如果您不想以任何方式使用界面。你可以使用

İtem.GetType().GetProperty("propertyName") ...

【讨论】:

不是比as慢吗? 是的。让我解释一下我的答案

以上是关于C# 包含继承类的基类数组,访问非继承字段的主要内容,如果未能解决你的问题,请参考以下文章

大型程序的工具——多重继承与虚继承

详解C++中基类与派生类的转换以及虚基类

c#基础 继承和接口,扩展类型

4月14日继承与多态

C#:在继承的子类中初始化基类字段,并访问基类字段,方法

c#核心基础--类的继承