2

I have an abstract class Detail, and four classes Rock, Grass, Tree, and Bush which extend Detail.

Tree and Bush have a Fruit property, but the others do not

I have a Detail[] which contains all 4 types of detail, and given an index I need to find that detail's fruit, if it has any.

I don't want to put the Fruit property in the base class Detail because not all details have fruit, and different kinds of detail have entirely different properties.

How can I get the Fruit of, for example, Detail[17] without knowing what kind of detail it is beforehand, or whether it has fruit (perhaps returning null if there is none)? Keeping in mind there will be possibly hundreds of different types of details with dozens of possible properties.

I'm imagining some kind of tagging system where each item in the array may or may not have one of several tags, but this is the closest I've managed so far.

2 Answers2

4

Make Tree and Bush and other subclasses that has a Fruit property implement IHasFruit, which looks like this:

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 {
    ...
}

Now, you can write a GetFruit method:

public Fruit GetFruit(int index) {
    Detail detail = details[index];
    return (detail as IHasFruit)?.Fruit; // this will return null if the detail has no fruit.
}
Sweeper
  • 213,210
  • 22
  • 193
  • 313
0

You can hava IHasFruit interface as well for the classes which gives fruit and then you can loop through by your interface.

IHasFruit [] myArray

Or if you need to use

Detail[] myArray
foreach (var item in myArray)
{
     If (item  is IHasFruit hasFruit)
         //do whatever
}

Or with reflection (slower)

Detail[] myArray
foreach (var item in myArray)
{
     var hasFruit= item.GetType().GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IHasFruit<>));
}

Or if you don't want to use interface in any way. You can use

İtem.GetType().GetProperty("propertyName") ...
Derviş Kayımbaşıoğlu
  • 28,492
  • 4
  • 50
  • 72