Я знаю, что это странное название, и я знаю, что наследование невозможно с перечислениями, поэтому позвольте мне объяснить.
Если у меня есть следующие классы:
- Fruit (аннотация)
- Яблоко (бетон - полученный из фруктов)
- Апельсин (бетон - полученный из фруктов)
И у меня есть следующий метод, реализованный с использованием обобщений:
public ICollection<T> FindFruit<T>() where T : Fruit
{
return _fruitRepository
.Fruits
.OfType<T>()
.ToList();
}
И я использую это так:
var apples = _fruitServices.FindFruit<Apple>();
Все хорошо.
Теперь - в настоящее время у меня есть следующее перечисление:
public enum FruitAssociations
{
Color,
Manufacturers
}
По сути, у "Fruit" может быть много ассоциаций, которые обозначают, какие ассоциации включить в результат из моего репозитория.
Таким образом, приведенный выше метод FindFruit
на самом деле выглядит следующим образом:
public ICollection<T> FindFruit<T>(FruitAssociations[] assocs) where T : Fruit
{
return _fruitRepository
.Fruits
.OfType<T>()
.IncludeAssocs(assocs) // ObjectQuery<Fruit> extension method.
.ToList();
}
Вот этот метод расширения:
public static ObjectQuery<Fruit> IncludeAssocs(this ObjectQuery<Fruit> source, FruitAssociations[] assocs)
{
if (assocs.Contains(FruitAssociations.Color))
query = query.Include("Color");
// etc
}
Также отлично работает.Однако проблема, с которой я сейчас сталкиваюсь, заключается в том, что у меня есть ассоциации по конкретным фруктам.
Например
public enum OrangeAssociations
{
OrangeFamilies
}
И я не уверен, как получить один FindFruit
метод, который способен возвращать ассоциации на основе типа T.
Это конечный результат, который я хотел бы сделать:
var oranges = _fruitServices.FindFruit<Orange>(new[] { OrangeAssociations.OrangeFamilies });
var apples = _fruitServices.FindFruit<Apple>(new[] { AppleAssociations.AppleFamilies });
Но я не могу понять, как это сделать, не имея отдельных FindFruit
методов для каждого типа фруктов и, следовательно, не преодолев точку общего параметра типа T.
Для тех, ктомне любопытно, что я здесь делаю - я использую энергичную загрузку с Entity Framework 4 и, следовательно, использую метод .Include
(который принимает строку, обозначающую навигационное свойство).Так что мой сервис принимает массив перечислений для данной сущности, затем я использую метод расширения, чтобы перевести его в строку, используемую в операторе .Include
.
Я думаю, что решение состоит в том, чтобы вместо принятиямассив перечислений, принять универсальный класс:
public ICollection<T> FindFruit<T>(FruitAssociations<T> assocs) where T : Fruit
И использовать его так:
var associations = new FruitAssociations<Orange>(OrangeAssociations.OrangeFamilies);
var apples = _fruitServices.FindFruit<Apple>(associations);
Но я не уверен, как это будет работать, или как его реализовать.
Надеюсь, мой вопрос имеет смысл и не слишком длинный / сложный.