C # массив базового класса, содержащий унаследованные классы, доступ к не наследуемым полям - PullRequest
0 голосов
/ 13 декабря 2018

У меня есть абстрактный класс Detail и четыре класса Rock, Grass, Tree и Bush, которые расширяют Detail.

Tree и Bush имеют свойство Fruit, но другие не

У меня есть деталь [], которая содержит все 4 типа деталей, и с учетом индекса мне нужно найти фрукты этой детали, если они есть.

Я не хочу помещать свойство Fruit в базуКласс Detail, потому что не все детали имеют фрукты, а разные виды деталей имеют совершенно разные свойства.

Как я могу получить Фрукт, например, Деталь [17], не зная, какая это детальзаранее, или есть ли у него фрукт (возможно, возвращающий ноль, если его нет)?Имея в виду, возможно, будут сотни различных типов деталей с десятками возможных свойств.

Я представляю какую-то систему тегов, где каждый элемент в массиве может иметь или не иметь один из нескольких тегов,но это самое близкое, что мне удалось до сих пор.

Ответы [ 2 ]

0 голосов
/ 13 декабря 2018

Make Tree и Bush и другие подклассы, которые имеют свойство 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.
}
0 голосов
/ 13 декабря 2018

Вы также можете иметь интерфейс 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") ...
...