【发布时间】:2019-01-16 04:11:43
【问题描述】:
我正在开发一个应用动态 linq 查询的 c# dll 库。 我已经定义了一个通用接口和一个通用日期类型,如下所示:
public interface IRangeValue<T> where T : struct
{
Nullable<T> GetHigh();
Nullable<T> GetLow();
void SetHigh(Nullable<T> val);
void SetLow(Nullable<T> val);
}
public class RangeT<T> : IRangeValue<T>
where T :struct
{
public Nullable<T> High { get; set; }
public Nullable<T> Low { get; set; }
public Nullable<T> GetHigh() { return High; }
public Nullable<T> GetLow() { return Low; }
public void SetHigh(Nullable<T> val) { High = val; }
public void SetLow(Nullable<T> val) { Low = val; }
}
然后我在我的代码中使用通用日期类型,如下所示:
public static Expression<Func<T, bool>> RangeCompare<T>(Expression<Func<T, DateTime>> selector, RangeT<DateTime> patten)
{
Expression<Func<T, bool>> predicate = PredicateBuilder.True<T>();
if (patten.GetHigh().HasValue)
{
predicate = predicate.And<T>(s => selector.Compile()(s) <= patten.GetHigh().Value);
}
if (patten.GetLow().HasValue)
{
predicate = predicate.And<T>(s => selector.Compile()(s).Equals(patten.GetLow().Value));
}
return predicate;
}
public static Expression<Func<T, bool>> RangeCompare<T>(Expression<Func<T, int>> selector, RangeT<int> patten)
{
Expression<Func<T, bool>> predicate = PredicateBuilder.True<T>();
if (patten.GetHigh().HasValue)
{
predicate = predicate.And<T>(s => selector.Compile()(s) <= patten.GetHigh().Value);
}
if (patten.GetLow().HasValue)
{
predicate = predicate.And<T>(s => selector.Compile()(s) >= patten.GetLow().Value);
}
return predicate;
}
实际上,如果我忽略输入类型,这两个方法的主体是相同的。所以我尝试编写一个新的泛型方法来替换这两种方法。新方法如下:
public static Expression<Func<T, bool>> RangeCompare<T>(Expression<Func<T, K>> selector, IRangeValue<K> patten)
{
Expression<Func<T, bool>> predicate = PredicateBuilder.True<T>();
if (patten.GetHigh().HasValue)
{
predicate = predicate.And<T>(s => selector.Compile()(s) <= patten.GetHigh().Value);
}
if (patten.GetLow().HasValue)
{
predicate = predicate.And<T>(s => selector.Compile()(s) >= patten.GetLow().Value);
}
return predicate;
}
我将参数 RangeT(RangeT) 替换为 IRangeValue。 现在编译器告诉我像'='这样的运算符错误,因为无法推断出泛型类型K
所以我的问题是:有什么方法可以实现泛型方法吗?
【问题讨论】:
-
为什么不在接口中定义属性而不是get和set方法?
-
相信你想用
Expression.LessThanOrEqual和Expression.GreaterThanOrEqual。 -
你不需要
RangeCompare来拥有K泛型类型参数吗?如果您仍然要调用Compile(),为什么要将selector传递为Expression<Func<>>而不仅仅是Func<>? -
您是使用 LINQ to SQL 还是 EF,还是全部使用 LINQ to Objects?