Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何在泛型类中映射默认LINQ表达式

如何在泛型类中映射默认LINQ表达式
EN

Stack Overflow用户
提问于 2013-09-26 05:21:36
回答 2查看 1.1K关注 0票数 4

我有一个通用的Repo类,它公开了一个数据库LINQ提供程序:

代码语言:javascript
运行
AI代码解释
复制
class Repo<T> where T : IPersisted
{
    IQueryable<T> Get()
    {
        return _queryable;
    }
}

(IPersisted是持久化对象的简单标记接口)。

现在..。我希望找到一种为某些派生类型的IPersisted注入默认LINQ表达式的优雅方法。例如,对于以下IPersisted实现:

代码语言:javascript
运行
AI代码解释
复制
class Deletable : IPersisted
{
    bool IsDeleted { get; set; }
}

我希望IQueryable<T> Get()方法返回_queryable.Where(q => !q.IsDeleted),只有在T类型为Deletable时才返回。

我考虑创建某种类型的字典映射IDictionary<Type, Expression>,并在Get方法中查找typeof(T),但我不确定在本例中是否能够强键入表达式。

如何根据Get T__的类型将“默认”LINQ表达式注入到__方法中?我希望有一种可扩展的、面向对象的方法将类型映射到默认表达式。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-09-26 06:05:05

因为每个IPersisted类型都有自己的表达式,所以我会将其作为IPersisted的一个约束。所以现在你有了某种多态。

有点像?

代码语言:javascript
运行
AI代码解释
复制
interface IPersisted<T> where T: IPersisted<T>
{
    Expression<Func<T, bool>> Predicate { get; }
}

class Repo<T> where T : IPersisted<T>, new()
{
    public IQueryable<T> Get()
    {
        var dummy = new T();
        return _queryable.Where(dummy.Predicate);
    }
}

class Deletable : IPersisted<Deletable>
{
    public Deletable()
    {

    }

    public Expression<Func<Deletable, bool>> Predicate
    {
        get { return x => !x.IsDeleted; }
    }

    bool IsDeleted { get; set; }
}

我认为这里需要的是某种静态多态,but since C# doesnt offer that,您可能需要为自己创建一个虚拟实例,以获得表达式。

如果不能使用默认构造函数,则可以依赖FormatterServices.GetUninitializedObject(t)。您可以像这样调整Get方法:

代码语言:javascript
运行
AI代码解释
复制
public IQueryable<T> Get()
{
    var dummy = (T)FormatterServices.GetUninitializedObject(typeof(T));
    return _queryable.Where(dummy.Predicate);
}

关于FormatterServices.GetUninitializedObject可能需要注意的许多事情中的两件事

  1. It will not initialize anything or run the constructor,但这对我们来说不应该是个问题。
  2. It's relatively slower。应该没什么大不了的,因为您可以缓存实例:),类似于: 类Repo,其中T: IPersisted {//缓存机制:这只在每个实例中运行一次;如果只在整个应用程序的整个生存期内运行一次,则可以使它//静态;

如果确切的表达式不重要,那么您可以去掉对象实例化。类似于:

代码语言:javascript
运行
AI代码解释
复制
interface IPersisted<T> where T: IPersisted<T>
{
    Func<T, bool> Predicate { get; }
}

class Repo<T> where T : IPersisted<T>
{
    public IQueryable<T> Get()
    {
        return _queryable.Where(x => x.Predicate(x));
    }
}

class Deletable : IPersisted<Deletable>
{
    public Func<Deletable, bool> Predicate
    {
        get { return x => !x.IsDeleted; }
    }
}

如果保留IPersisted的原始定义很重要,那么您可以将其非泛型化。不确定这是否会使它的类型更少。

代码语言:javascript
运行
AI代码解释
复制
interface IPersisted
{
    Expression<Func<object, bool>> Predicate { get; }
}

class Repo<T> where T : IPersisted
{
    public IQueryable<T> Get()
    {
        return _queryable.Where(dummy.Predicate);
    }
}

class Deletable : IPersisted
{
    public Expression<Func<object, bool>> Predicate
    {
        get { return x => !((Deletable)x).IsDeleted; }
    }
}

通过在IPersisted中使用一个方法,可以使上述方法具有更强的类型,但不一定需要足够好的约束:

代码语言:javascript
运行
AI代码解释
复制
interface IPersisted
{
    Expression<Func<T, bool>> GetPredicate<T>() where T : IPersisted;
}

class Repo<T> where T : IPersisted
{
    public IQueryable<T> Get()
    {
        return _queryable.Where(dummy.GetPredicate<T>());
    }
}

class Deletable : IPersisted
{
    Expression<Func<T, bool>> IPersisted.GetPredicate<T>() //made it explicit
    {
        return x => ((Deletable)(object)x).IsDeleted;
    }
}

注意:如果Predicate实现在Repo<T>类之外没有意义,则将其显式化。

票数 3
EN

Stack Overflow用户

发布于 2013-09-26 05:37:50

不确定我们是否100%在同一个页面上,但是这个get方法示例将采用linq,您可以使用它作为where子句来过滤查询。

代码语言:javascript
运行
AI代码解释
复制
class Repo<T> where T : IPersisted
{
    IQueryable<T> Get(Func<T, bool> filter)
    {
        return _queryable.Where(filter);
    }
}

编辑:不确定这是否能很好地转化为sql,但为了确保我对你想要的东西有正确的想法(也许还会引发一丝希望):你考虑过这样的事情吗?

代码语言:javascript
运行
AI代码解释
复制
class Repo<T> where T : IPersisted
{
    IQueryable<T> Get()
    {
        if (typeof (T).IsAssignableFrom(typeof (IDeletable)))
        {
            return _queryable.Where(o => ((IDeletable) o).Deleted = false).AsQueryable();
        }
        return _queryable;
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19029510

复制
相关文章
TestNG忽略测试和预期异常
一.有时候我们写的代码还没有构思完整, 但测试case又需要执行,testng提供了@Test (Enable=false) ,可以有助于禁用.
louiezhou001
2020/02/25
8860
策略模式:处理不同策略具有不同参数的情况
策略模式确实在处理不同策略需要不同参数的情况下会显得有些复杂。然而,这并不意味着策略模式不能在这种情况下使用。有几种可能的解决方案:
运维开发王义杰
2023/08/16
7060
策略模式:处理不同策略具有不同参数的情况
Junit 4 Tutorials(Junit 4 教程) 四、Junit4 参数化测试
Junit 4 参数化测试 允许通过变化范围的参数值来测试方法。参数擦测试可以通过以下简单的步骤实现:
亦山
2021/09/14
6010
JUnit5参数化测试的几种方式
参数化测试一直是津津乐道的话题,我们都知道JMeter有四种参数化方式:用户自定义变量、用户参数、CSV文件、函数助手,那么JUnit5有哪些参数化测试的方式呢?
dongfanger
2021/07/20
1.2K0
JUnit5参数化测试的几种方式
JUnit4 参数化测试( Parameterized tests)
  当类被@RunWith注解修饰,或者类继承了一个被该注解修饰的类,JUnit将会使用这个注解所指明的运行器(runner)来运行测试,而不使用JUnit默认的运行器。
明明如月学长
2021/08/27
3.2K0
Spring Boot Junit4 参数化测试Controller
由于Spring测试类上只能有一个@Runwith注解,如果使用@RunWith(Parameterized.class),就无法s使用@RunWith(SpringJUnit4ClassRunner.class)。
明明如月学长
2021/08/27
9590
Junit 实例精讲基础教程(五) JUnit套件测试,一次性运行多个测试用例(测试类的测试方法)
前面我们已经了解了使用Junit进行单个方法的测试、以及如何模拟超时测试和异常测试,抛出一个问题:我不想一个一个地去跑测试用例,应该怎么办呢?Junit套件测试为我们提供了解决方案,它可以使用@RunWith(Suite.class)注解结合@Suite.SuiteClasses({Class1.class, Class2.class,… })注解来一次性执行Class1、Class2,…多个测试用例的测试方法。
青山师
2023/05/04
1.6K0
Junit 实例精讲基础教程(五) JUnit套件测试,一次性运行多个测试用例(测试类的测试方法)
Junit5参数化实战,让测试更优雅
在代码的世界里,有一片自动化的花园,那里的用例是微风吹拂下的花朵,绽放着不同的颜色。在这片花园中,我们常常遇到一个美妙的情景:相同的测试流程,却需要随着业务的风向,切换不同的测试数据。这就像是一支曲子,相同的旋律,却因音符的不同而显得迥然不同。
测试蔡坨坨
2023/09/11
5811
Junit5参数化实战,让测试更优雅
软件测试|Junit5 实现参数化和数据驱动
登录:不同的用户名,不同的密码,不同的组合都需要做登录场景的测试,正常的排列组合下可能会产生多个用例
霍格沃兹测试开发Muller老师
2023/01/09
1.3K0
Junit测试 - mockMVC
使用mock工具可以直接模拟http请求,不用直接产生网络的请求环境,简化了测试流程。
Tim在路上
2020/08/04
1.4K0
如何用Junit5玩出参数化测试的新花样?
这是之前一篇文章《用junit5编写一个类ZeroCode的测试框架》的续集。主要将在之前工作的基础上,围绕参数化测试展开。 框架主要设计点:
Criss@陈磊
2019/12/05
1.5K0
如何用Junit5玩出参数化测试的新花样?
如何用Junit5玩出参数化测试的新花样?
这是之前一篇文章《用junit5编写一个类ZeroCode的测试框架》的续集。主要将在之前工作的基础上,围绕参数化测试展开。 框架主要设计点:
Antony
2020/12/01
9480
如何用Junit5玩出参数化测试的新花样?
JUnit5参数化测试扩展3案例
在参数化测试方面,JUnit5提供了较为丰富的数据源,如@ValueSource,支持提供int、float等基本类型以及String和Class等作为参数,@CsvSource可以提供CSV格式的数据。另外还可以通过@MethodSource来提供任意类型的数据。
Antony
2021/06/28
9580
同时使用Junit4的@Parameterized参数化测试和Spring容器
同时使用Junit4的@Parameterized参数化测试和Spring容器整合 ---- 之剑 2016.4.30 整合Spring容器 @SpringApplicationConfiguration(classes = Application.class) @WebAppConfiguration public class TestBase { @Autowired protected TedaCaseService tedaCaseService; private TestCon
一个会写诗的程序员
2018/08/20
6700
SpringBoot异常处理五种方式、Junit单元测试、热部署
首先说明一下,这里使用的是Springboot2.2.6.RELEASE版本,由于Springboot迭代很快,所以要注意版本问题。
别先生
2020/05/26
8450
Junit单元测试
JUnit 是一个 Java 编程语言的单元测试框架。JUnit 在测试驱动的开发方面有很重要的发展,是起源于 JUnit 的一个统称为 xUnit 的单元测试框架之一。
共饮一杯无
2022/11/28
8930
Junit 4 Tutorials(Junit 4 教程) Junit4 七、超时测试
Junit 4超时测试(Timeout test)可以被用来测试方法的执行时间。 Junit 4 超时测试可以被用在:
亦山
2021/09/14
9250
Myexclipse创建Junit测试
. 下载JUnit的jar文件,下载地址在这里 2. 在MyEclipse中新建一个要测试的项目HelloJUnit 3. 添加一个要测试的类HelloJUnit,代码如下,注意需要先建package Java代码   package com.yukaizhao;   public class HelloJUnit {   public String getMessage(){   return "Hello Junit";       }   }   4. 新建一个单元测试项
xiangzhihong
2018/02/01
7860
Myexclipse创建Junit测试
Junit测试类使用
ha_lydms
2023/08/10
1740
【软件测试】JUnit详解
JUnit是一个用于编写和运行Java程序单元测试的开源框架。 它提供了一组注解和断言方法,以及用于执行测试的测试运行器。通过使用JUnit,开发人员可以轻松地编写自动化测试用例,验证代码的正确性,并且能够快速地发现和修复bug。JUnit的使用可以提高代码的质量和可维护性,同时也有助于进行持续集成和持续测试。它被广泛应用在Java开发领域中,成为了标准的单元测试框架之一。
xxxflower
2023/10/16
5710
【软件测试】JUnit详解

相似问题

具有多个测试的参数化junit测试

30

JUnit测试-分析预期的异常

112

组织预期异常的junit测试

24

JUnit中的多个预期异常

26

Junit测试:测试多个异常

44
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档