Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在为内存集合实现规范模式时塑造数据的优雅方式_C#_.net_Ienumerable_Specification Pattern - Fatal编程技术网

C# 在为内存集合实现规范模式时塑造数据的优雅方式

C# 在为内存集合实现规范模式时塑造数据的优雅方式,c#,.net,ienumerable,specification-pattern,C#,.net,Ienumerable,Specification Pattern,是否有任何健壮、优雅和/或标准的方法来实现内存集合的规范模式(IEnumerable,而不是IQueryable),包括对结果进行整形/投影 对标准使用Func显然只包括Where子句/方法,而不是Select 到目前为止,我提出的想法是,我可以在我的规范中包含另一个委托(没有双关语),它专门涉及Select操作。实现可能如下所示。正如您在底部看到的,存储库只执行Where和Select,传递规范的委托成员 这个解决方案似乎很管用,但我在很多场合发现,对于我正在解决的问题,存在着更好的解决方案,

是否有任何健壮、优雅和/或标准的方法来实现内存集合的规范模式(
IEnumerable
,而不是
IQueryable
),包括对结果进行整形/投影

对标准使用
Func
显然只包括
Where
子句/方法,而不是
Select

到目前为止,我提出的想法是,我可以在我的规范中包含另一个委托(没有双关语),它专门涉及
Select
操作。实现可能如下所示。正如您在底部看到的,存储库只执行
Where
Select
,传递规范的委托成员

这个解决方案似乎很管用,但我在很多场合发现,对于我正在解决的问题,存在着更好的解决方案,因此提出这个问题似乎是合理的

(我计划采用规范模式的原因是,我的应用程序可能需要以各种形状显示来自内存中复杂对象集合的大量结果,并且将查询内容保存在一个易于查找/管理的地方会很整洁。但请随意提出完全不同的建议。)

内部接口IMYS规范
{
Func其中{get;}
Func选择{get;}
布尔满意(tenty t);
// ...  
}
内部接口存储器
{
// ...
TResult GetSingle(IMySpecification规范);
IEnumerable列表(IMySpecification规范);
}
内部类MyGenericRepository:IMyRepository
{
受保护的IEnumerable集合;
公共MyGenericRepository(IEnumerable列表)
=>\u集合=列表;
// ...
public TResult GetSingle(IMySpecification规范)
=>列表(规范).Single();
公共IEnumerable列表(IMYSSpecification规范)
=>(IEnumerable)\u collection.Where(spec.Where).Select(spec.Select);
}

在评论中进行了简短的讨论后,我认为适合回答我自己的问题:

您通常不应该这样做。

如果你在这里结束,因为你想要实现同样的事情,你可能需要退后一步,考虑你真正想要解决的问题。 通过将规范与数据成形结合起来,您在很大程度上挫败了规范的目的:规范不能再以灵活的方式被多个使用者使用,因为不同的使用者可能非常希望使用不同形状的数据、链接/组合规范等

  • 如果您不需要这种灵活性,那么您可能可以从设计中删除规范层(例如,只需公开存储库中的方法)
  • 如果您确实需要这种灵活性,请让消费者塑造/映射数据

(如果您有任何需要添加的内容,请随意编辑此答案。)

我只想跳过通用存储库(或者至少不将其公开给您的业务/应用程序层),使用特定方法(如
GetCustomerWithOrders()
等)选择普通存储库。现在,您只是将属于同一个不必要的抽象的代码分割开来。规范模式的唯一原因是根据参数以多种方式进行非常灵活的过滤。转换部分与此无关。@Gabor-几年前我实现了类似的功能,效果非常好。我同意Alexander关于Select和Where是唯一不同的东西的观点,但是我不会把这个概念强加到您的规范中。原因:一个消费者可能想要字段1和2,而另一个消费者想要字段1和3,即使他们都只想要“活动”项(即……您的规格)。我所做的是使用AutoMapper的投影来完成Select在您的示例中所做的工作。通过这种方式,您可以使用TResult作为AM的ProjectTo方法的类型,并让它解决所有问题。下面是指向AM提供投影的扩展库的链接:谢谢,@AlexanderDerck,也许我会留下它。我只是很失望,几乎我所有的问题最终都意识到我是想把一个方形的钉子塞进一个圆形的洞里…:D@GaborBarat我想我们大多数人时不时都会这样。当我在寻找正确的抽象概念时,我试着退一步,看看更大的图景。我想解决的问题到底是什么?这个问题的哪些部分可以用我的抽象来解决?每个人都喜欢时不时地过度工程;-)