问题
I want to write an extension method for a collection of objects that uses base class as a type requirement. I understand this is not necessarily the best way to do things, but I am curious because I'm interested in learning the nuances of the language. This example explains what I would like to do.
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
The only way I can get the extension method to expose is to create a collection of Humans. Is it possible to call this type of extension method on derived types as long as I only reference members of the base type?
回答1:
Your code will actually compile as is with the C# 4 compiler, as that version supports contravariant type parameters.
To get it working with C# 3, you can create a generic extension method for IEnumerable<T>
with a where T : Human
constraint that acts on the generic type, instead of specifically only for IEnumerable<Human>
:
public static void HappinessStatus<T>(this IEnumerable<T> items) where T : Human
{
foreach (T item in items)
{
Console.WriteLine(item.IsHappy.ToString());
}
}
Then you can call the extension method on your List<Woman>
collection as you describe.
来源:https://stackoverflow.com/questions/5428178/extension-method-for-a-collection-of-derived-types-with-base-type-in-method-sign