gpt4 book ai didi

c# - 模拟多态/泛型枚举 - C#

转载 作者:行者123 更新时间:2023-11-30 14:41:17 30 4
gpt4 key购买 nike

我知道这是一个奇怪的标题,我知道枚举不可能继承,所以让我解释一下。

如果我有以下类(class):

  • 水果(摘要)
    • 苹果(具体——源自水果)
    • 橙色(具体 - 源自水果)

我有以下方法,用泛型实现:

public ICollection<T> FindFruit<T>() where T : Fruit
{
return _fruitRepository
.Fruits
.OfType<T>()
.ToList();
}

我是这样使用它的:

var apples = _fruitServices.FindFruit<Apple>();

一切顺利。

现在 - 我目前有以下枚举:

public enum FruitAssociations
{
Color,
Manufacturers
}

基本上一个“水果”可以有很多关联,这指定了哪些关联要包含在我的存储库的结果中。

所以上面的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
}

而且我不确定如何使用能够返回基于 T 类型的关联的单个 FindFruit 方法。

这是我希望能够做到的最终结果:

var oranges = _fruitServices.FindFruit<Orange>(new[] { OrangeAssociations.OrangeFamilies });
var apples = _fruitServices.FindFruit<Apple>(new[] { AppleAssociations.AppleFamilies });

但是如果没有针对每种水果类型的单独FindFruit 方法,我无法弄清楚如何做到这一点,因此破坏了通用 T 类型参数的要点。

对于那些对我在这里做什么感到好奇的人 - 我正在使用 Entity Framework 4 的预加载,因此使用 .Include 方法(它采用指定导航的字符串属性(property))。因此,我的服务接受给定实体的枚举数组,然后我使用扩展方法将其转换为 .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);

但我不确定这将如何运作,或者如何实现。

希望我的问题有道理并且不会太长/太复杂。

最佳答案

Eric Lippert 会来我家并为此用棍子打我,但它有效。

用法:

// finds fruits of type Orange, includes Color and OrangeFamilies
var result = FindFruit(OrangeAssociation.Color,
OrangeAssociation.OrangeFamilies);

// finds fruits of type Fruit, includes Manufacturers
var result = FindFruit(FruitAssociation.Manufacturers);

实现:

static ICollection<TFruit> FindFruit<TAssoc, TFruit>(
params FruitAssociation<TAssoc, TFruit>[] assocs)
where TAssoc : FruitAssociation<TAssoc, TFruit>, new()
where TFruit : Fruit
{
var query = _fruitRepository.Fruits.OfType<TFruit>();

foreach (var assoc in assocs)
{
query = query.Include(assoc.Name);
}

return query.ToList();
}

abstract class FruitAssociation<TAssoc, TFruit>
where TAssoc : FruitAssociation<TAssoc, TFruit>, new()
where TFruit : Fruit
{
public static readonly TAssoc Color = Define("Color");

public static readonly TAssoc Manufacturers = Define("Manufacturers");

protected static TAssoc Define(string name)
{
return new TAssoc { Name = name };
}

public string Name
{
get;
private set;
}
}

sealed class FruitAssociation : FruitAssociation<FruitAssociation, Fruit>
{
}

sealed class OrangeAssociation : FruitAssociation<OrangeAssociation, Orange>
{
public static readonly OrangeAssociation OrangeFamilies =
Define("OrangeFamilies");
}

关于c# - 模拟多态/泛型枚举 - C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4393879/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com