C# DateTime作为类泛型约束

C# DateTime作为类泛型约束,c#,generics,C#,Generics,在C#中是否有一种方法可以添加一个类约束,以确保类型是日期时间还是可为空?或者确保他们有一个与日期时间兼容的==运算符 下面是一个简化的用例,我尝试在两个实体之间重复使用一个方法。实际上,它在四个不同的实体之间重复使用。所有用户都共享一个“相似”界面,但有些用户有一个DateTime?,而另一些用户的创建的属性有DateTime 我只需要确保它们可以与另一个方法获取的特定的DateTime进行比较getdateforlastmount() 限制是我无法更改实体的属性。不过,我可以为它们添加新接口

在C#中是否有一种方法可以添加一个类约束,以确保
类型
日期时间
还是
可为空
?或者确保他们有一个与
日期时间
兼容的
==运算符

下面是一个简化的用例,我尝试在两个实体之间重复使用一个方法。实际上,它在四个不同的实体之间重复使用。所有用户都共享一个“相似”界面,但有些用户有一个
DateTime?
,而另一些用户的
创建的
属性有
DateTime

我只需要确保它们可以与另一个方法获取的特定的
DateTime
进行比较
getdateforlastmount()

限制是我无法更改实体的属性。不过,我可以为它们添加新接口。我无法从
GetDateForLastMonth
更改返回的
类型

public class Context : DbContext
{
    public virtual DbSet<OrderEntity> Orders { get; set; }
    public virtual DbSet<InvoiceEntity> Invoices { get; set; }

    public IEnumerable<T> GetItemsForSomePeriod<T, TDateType>(DbSet<T> dbSet) 
        where T : class, IHaveACreationDate<TDateType> 
        where TDateType : DateTime // Does not compile because "Only class or interface could be specified as constraint"
    {
        DateTime someDate = GetSomeDate();
        DateTime someOtherDate = GetSomeOtherDate();
        DateTime someThirdDate = GetAThirdDate();
        return dbSet
            .Where(x => (x.Created == lastMonth || x.Created == someOtherDate ||  x.Create == someThirdDate)) // Cannot compare because Created and someDate isn't same Type
            .ToArray();
    }
}

public interface IHaveACreationDate<T>
{
    T Created { get;}
}

public class OrderEntity: IHaveACreationDate<DateTime?>
{
    public DateTime? Created { get; set; }

}

public class InvoiceEntity : IHaveACreationDate<DateTime>
{
    public DateTime Created { get; set; }
}
公共类上下文:DbContext
{
公共虚拟数据库集命令{get;set;}
公共虚拟数据库集{get;set;}
公共IEnumerable GetItemsForSomePeriod(DbSet DbSet)
其中T:class,i保存日期
其中,TDateType:DateTime//未编译,因为“只能将类或接口指定为约束”
{
DateTime someDate=GetSomeDate();
DateTime someOtherDate=GetSomeOtherDate();
DateTime someThirdDate=GetAThirdDate();
返回数据集
.Where(x=>(x.Create==lastMonth | | x.Created==someOtherDate | | x.Create==someThirdDate))//无法比较,因为Created和someDate的类型不同
.ToArray();
}
}
公共接口IHaveACreationDate
{
T创建了{get;}
}
公共类OrderEntity:IHaveACreationDate
{
公共日期时间?已创建{get;set;}
}
公共类发票实体:IHaveACreationDate
{
已创建公共日期时间{get;set;}
}

一个更好的问题是为什么要将
GetItemsForLastMonth
设置为通用?更重要的是,当您真正需要的是
Where
子句的表达式时,为什么还要处理任意的
DbSet
?如果您愿意,您可以在IQueryable上创建一个扩展方法,假设所有T都实现了提供
Created
的相同接口,例如
IQueryable ForLastMonth(IQueryable查询)=>query.Where(x=>x.Created==lastMonth)
一个只适用于两种非常特定类型的函数有什么通用性?不,泛型是这里最重要的东西。只需编写两个重载,一个用于
DateTime
,一个用于
DateTime?
。问题是,编译器必须选择一个
=
操作符来生成对的调用。作为编译器,显然它必须在编译时这样做。没有基于具体类型的专门化。您是否试图在DbSet repository之上创建某种类型的“repository”?@smoksnes
.Where().Where().Where()
工作并基本上创建一个
子句。如果您想要
,可以在表达式中使用
| |
,更好的问题是为什么要将
GetItemsForLastMonth
设置为泛型?更重要的是,当您真正需要的是
Where
子句的表达式时,为什么还要处理任意的
DbSet
?如果您愿意,您可以在IQueryable上创建一个扩展方法,假设所有T都实现了提供
Created
的相同接口,例如
IQueryable ForLastMonth(IQueryable查询)=>query.Where(x=>x.Created==lastMonth)
一个只适用于两种非常特定类型的函数有什么通用性?不,泛型是这里最重要的东西。只需编写两个重载,一个用于
DateTime
,一个用于
DateTime?
。问题是,编译器必须选择一个
=
操作符来生成对的调用。作为编译器,显然它必须在编译时这样做。没有基于具体类型的专门化。您是否试图在DbSet repository之上创建某种类型的“repository”?@smoksnes
.Where().Where().Where()
工作并基本上创建一个
子句。如果需要
,可以在表达式中使用
|