Метод расширения для коллекции производных типов с базовым типом в сигнатуре метода - PullRequest
3 голосов
/ 25 марта 2011

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

public class Human { public bool IsHappy { get; set; } }
public class Man : Human { public bool IsSurly { get; set; } }
public class Woman : Human { public bool IsAgreeable { get; set; } }

public static class ExtMethods
{
    public static void HappinessStatus(this IEnumerable<Human> items)
    {
        foreach (Human item in items)
        {
            Console.WriteLine(item.IsHappy.ToString());
        }
    }
}

// then in some method, I wish to be able to do the following

List<Woman> females = RetreiveListElements(); // returns a list of Women
females.HappinessStatus(); // prints the happiness bool from each item in a collection

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

1 Ответ

6 голосов
/ 25 марта 2011

Ваш код будет фактически скомпилирован с компилятором C # 4, так как эта версия поддерживает параметры контравариантного типа .

Чтобы заставить его работать с C # 3, вы можете создать универсальное расширениеметод для IEnumerable<T> с ограничением where T : Human, действующим на универсальный тип, а не только специально для IEnumerable<Human>:

public static void HappinessStatus<T>(this IEnumerable<T> items) where T : Human
{
    foreach (T item in items)
    {
        Console.WriteLine(item.IsHappy.ToString());
    }
}

Затем вы можете вызвать метод расширения в вашей коллекции List<Woman> какВы описываете.

...