2010-06-28 63 views
0

鑑於以下兩類:靜態方法/調用者的類類型推斷?

public class ABC 
{ 
    public void Accept(Ordering<User> xyz) 
    { 
     // Do stuff with xyz... 
    } 
} 

public class Ordering<TEntity> 
     where TEntity : class 
{ 
    private readonly Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> Transform; 

    private Ordering(Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> transform) 
    { 
     this.Transform = transform; 
    } 

    public static Ordering<TEntity> By<TKey>(Expression<Func<TEntity, TKey>> expression) 
    { 
     return new Ordering<TEntity>(query => query.OrderBy(expression)); 
    } 

    public static Ordering<TEntity> ByDescending<TKey>(Expression<Func<TEntity, TKey>> expression) 
    { 
     return new Ordering<TEntity>(query => query.OrderByDescending(expression)); 
    } 

    public Ordering<TEntity> ThenBy<TKey>(Expression<Func<TEntity, TKey>> expression) 
    { 
     return new Ordering<TEntity>(query => this.Transform(query).ThenBy(expression)); 
    } 

    public Ordering<TEntity> ThenByDescending<TKey>(Expression<Func<TEntity, TKey>> expression) 
    { 
     return new Ordering<TEntity>(query => this.Transform(query).ThenByDescending(expression)); 
    } 

    public IOrderedQueryable<TEntity> Apply(IQueryable<TEntity> query) 
    { 
     return Transform(query); 
    } 

} 

用於下列方式:

ABC abc = new ABC(); 
abc.Accept(Ordering<User>.By(u => u.Id)); 

有沒有什麼辦法來推斷的T類型,像這樣:

abc.Accept(Ordering.By(u => u.Id)); 

回答

4

你可以這樣做,但不是通用類型。像這樣的泛型類型推斷只發生在泛型方法上。聲明一個單獨的非 -generic類型,與通用方法:

public class XYZ 
{ 
    public static XYZ Action<T, TKey> (TKey key, T element) 
    { 
     return new XYZ<T>(element); 
    } 
} 

編輯:爲了響應問題編輯。

不,你不能做這樣的事情:

abc.Accept(Ordering.By(u => u.Id)); 

的問題是內表達:

Ordering.By(u => u.Id) 

什麼的u這裏的類型?它可以是任何具有Id屬性的類。請注意,C#編譯器需要在之前計算出此表達式的類型,它看起來是abc.Accept。即使abc.Accept只有工作Ordering<User>,它會失敗。

有三個選項的位置:

  • 使用泛型類的靜態方法,指定源類型參數明確,且推斷密鑰類型參數:

    Ordering<User>.By(u => u.Id) 
    
  • 使用在非泛型類中的泛型方法,明確指定兩個類型參數:

    Ordering.By<User, string>(u => u.Id) 
    
  • 在非泛型類使用泛型方法,指定拉姆達參數的類型明確,並讓編譯器推斷出密鑰類型參數:

    Ordering.By((User u) => u.Id) 
    

顯然,所有這些情況需要你在某處明確指定類型。

另一個選項是有點奇怪是相關的,如果你通常已經得到User(或至少一個該類型的變量)的實例。你可以使用它作爲一個例子,它會被忽略:

public static Ordering<T> By<T,TKey>(Expression<Func<T, TKey>> func, T example) 
{ 
    return By<T, TKey>(func); 
} 
... 

Ordering.By(u => u.Id, dummyUser); 
+0

我剛剛明白了這一點。我只是意識到我需要更新我的問題來複制我的問題。看到我上面的編輯。 – TheCloudlessSky 2010-06-28 14:28:07

+0

本質上,問題在於我實際上將'Expression >表達式'作爲參數傳遞。 – TheCloudlessSky 2010-06-28 14:42:57

+0

@ TheCloudlessSky:恐怕沒有看到更多的細節,很難知道推薦什麼。 – 2010-06-28 14:47:07