2013-02-26 31 views
0

我試圖編寫一個流暢的接口,它能夠在設計時檢測作爲Linq表達式傳遞的屬性類型,並根據該類型的評估返回一個接口。設計時動態返回接口

例如:

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; 
} 

包含和排除方法不同的接口由一個僅相差枚舉接受爲參數:

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); 
} 

我懷疑這是不可能的,但我不能它出來comp因爲動態可以做一些時髦的魔法。

我看了一些其他流利的接口,但似乎沒有評估表達式,以確定設計時返回什麼類型。

回答

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

您可以利用重載和類型推斷。事情是這樣的:現在

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)將返回IStringOperationsCanSearch(x => x.Age)將返回INumericOperations對象。

+0

我要試一試。謝謝! – 2013-02-26 22:00:21