我正在尝试编写一个流畅的界面,该界面能够在设计时检测作为Linq Expression传递的属性类型,并根据对该类型的评估返回一个接口。
例如:
public class Searchable<Person>
{
public Searchable()
{
CanSearch(x => x.Name)
.Include(StringOperations.Contains);
CanSearch(x => x.Age)
.Exclude(NumericOperators.GreaterThan);
}
}
在CanSearchMethod中,我希望能够做到这样的事情:
public IOperations CanSearch(Expression<Func<T, object>> expression)
{
var type = (/* Code to pick apart expression */);
if(type == typeof(int))
return new ClassImplementingINumericOperations();
if(type == typeof(string))
return new ClassImplementingIStringOperations();
if(type == typeof(IEnumerable))
return new ClassImplementingIIEnumerableOperations();
return null;
}
不同接口的Include和Exclude方法的区别仅在于作为参数接受的枚举:
public interface IOperations
{
}
public interface INumericOperations : IOperations
{
INumericOperations Include(NumericOperationsEnum op);
INumericOperations Exclude(NumericOperationsEnum op);
}
public interface IStringOperations : IOperations
{
IStringOperations Include(StringOperationsEnum op);
IStringOperations Exclude(StringOperationsEnum op);
}
public interface IIEnumerableOperations : IOperations
{
IIEnumerableOperations Include(CollectionOperationsEnum op);
IIEnumerableOperations Exclude(CollectionOperationsEnum op);
}
我怀疑这是不可能的,但我完全不能完全理解,因为动力学可以做一些时髦的魔术。
我已经查看了其他一些流畅的接口,但似乎没有人评估表达式,以确定在设计时要返回的类型。
答案 0 :(得分:1)
您可以使用重载编译时类型安全来执行此操作:
public IStringOperations CanSearch<T>(Expression<Func<T, string>> expression);
public IIEnumerableOperations<TItem> CanSearch<T, TItem>(Expression<Func<T, IEnumerable<TItem>> expression);
但是,对于数字类型,您需要为7种数字类型中的每一种都需要单独的重载,或者需要一种非常不灵活的通用INumericOperations<TNumber>
。
答案 1 :(得分:1)
您可以利用重载和类型推断。像这样:
IStringOperations CanSearch(
Expression<Func<T, string>> expression)
{ /* ... */ }
INumericOperations CanSearch<TCompare>(
Expression<Func<T, TCompare>> expression)
where TCompare : IComparable<TCompare>
{ /* ... */ }
IIEnumerableOperations CanSearch<TSeq>(
Expression<Func<T, IEnumerable<TSeq>>> expression)
{ /* ... */ }
现在,CanSearch(x => x.Name)
将返回IStringOperations
,而CanSearch(x => x.Age)
将返回INumericOperations
个对象。