2013-03-12 33 views
2

給出一個通用的方法Get<T>這需要以下參數...轉換泛型方法參數具體型號

Expression<Func<T,bool>> foo 

在這一方法的身體我想測試,如果「T」是的typeof(東西),如果是,然後抹上它:

Expression<Func<Stuff,bool>> boo = (???) foo; 

我想到的是第一反應「無需投它,它已經是Stuff類型的,如果這是在通過」但是我發現在方法調度方面不是這樣的!

所以是的,我需要測試和施放,但不知道如何。

下面是爲什麼和何處這是必要的上下文。

我有這樣的代碼:

public class Stuff { 
    public int Alpha; 
} 

interface ISomething { 
    List<T> Get<T>(Expression<Func<T,bool>> lambda); 
} 

public class Something : ISomething { 

    List<T> Get<T>(Expression<Func<T,bool>> expr){ 
     //... 

     //Makes non-recursive call to non-generic 'Get' method. 
     //Works as expected. 
     Get((Stuff x) => x.Alpha > 10); 

     //UH-OH! makes recursive call to Get<T> even when T is typeof(Stuff)! 
     //This is where casting is needed! 
     Get(expr); 

     //... 
    } 

    List<Stuff> Get(Expression<Func<Stuff,bool>> expr){ 
     //... 
    } 
} 

我的目的是爲具有通用的方法Get<T>調用非通用Get如果exprLambdaExpression特別需要Stuff類型的參數。但是,這不是在上面的代碼中發生的。

如果我運行此代碼...

ISomething foo = new Something(); 
var result = foo.Get((Stuff x) => x.Alpha < 20); 

...調用的函數是Get<T>。這並不令人驚訝,即使非通用的Get更好匹配,因爲Get<T>是ISomething接口中唯一可用的匹配。所以這是好的。

但是,一旦Get<T>方法執行,我希望非同義的Get與調用名爲expr相同的參數。鑑於我正在觀察的行爲,看起來好像我只能得到我想要的東西,如果我將Expression<Func<T,bool>>轉換爲Expression<Func<Stuff,bool>>。這也假定我有一個測試,如isas,以確認它是可澆注的。

如何完成類型測試,以及如何完成演員?

是否有另一種方法來強制更具體和非通用的Get方法被調用?請假定來電者只能通過ISomething界面工作。

當然,如果非通用的Get立即被調用而根本沒有經過Get<T>,那將更加理想。但是如果我被迫通過ISomething界面工作,我不認爲這是可能的。如果可以找到一種方法來完成這項工作 - 那麼它將提供與C++中的「traits - the else-then-if」有些相似的功能。

+0

你試過使用GetType()嗎? – theMayer 2013-03-12 04:18:01

+0

你能解釋一下你的用例好一點嗎?這個設計對我來說似乎過於複雜,我認爲有一個優雅的,面向對象的方法來簡化它。 – theMayer 2013-03-12 04:19:59

+0

@ rmayer06:在底部添加一個額外的評論和鏈接以闡明爲什麼這很有用。 – 2013-03-12 04:30:06

回答

3

怎麼是這樣的:

public List<T> Get<T>(Expression<Func<T,bool>> expr){ 
    var expr2 = expr as Expression<Func<Stuff, bool>>; 
    if (expr2 != null){ 
     return Get(expr2) as List<T>; 
    } 

    //... 
} 

此代碼ReSharper的嚇壞了,但它似乎工作:)

一個更好的選擇,如果可能的話,將添加非通用超載到ISomething。

+0

令人難以置信。這正是我嘗試的第一件事,並且發現它不起作用。我看到你的答案,並再次嘗試 - 它的工作原理。隨你!至少它有效。 :) – 2013-03-12 13:29:10

+0

我喜歡這個解決方案:-)但是我確實爲那些必須弄清楚你的代碼在這條路上做什麼的人感到抱歉...... ;-) – theMayer 2013-03-12 16:45:20