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