2013-02-25 78 views
2

我在創建一些流暢的API,一種DSL。我一直在遇到一個特定的問題,而我在這裏或其他地方找不到解決問題的辦法,它解決了我所看到的確切問題。另外,我看到很多人問這個問題的很多變化。通用類的擴展方法

這裏是什麼,我想做,顯然做作,樣品...

Run<Car>.Off<Road>(); 
Run<Car>.Off<Cliff>(); 
Run<Person>.Off<Road>(); 

Person pete = new Person(); 
pete.Run().Off<Road>(); 
pete.Run().Off<Cliff>(); 

最後兩行不會編譯給未知方法的錯誤。我認爲我需要使用擴展方法來實現它,如果這是可能的,但我一直無法提出一個可行的解決方案。以下是我迄今爲止...

public class Run<TActor, TTarget> 
{ 
    public Run() { } 
    public Run(TActor actor) { } 
    public Run(TActor actor, TTarget target) { } 

    public TActor Actor { get; set; } 
    public TTarget Target { get; set; } 
} 

public static class Run<TActor> 
{ 
    public static Run<TActor, TTarget> Off<TTarget>() 
    { 
     return new Run<TActor, TTarget>(); 
    } 
} 

我試着運行使得擴展方法,像下面,但後來我遇到與它的問題現在知道什麼TActor或t目標類型。

public static class RunExtensions 
{ 
    public static TRun Run<TRun>(this TRun run) where TRun : Run<TActor, TTarget> 
    { 
     // doesn't compile 
    } 

    public static Run<TActor, TTarget> Run<TActor>(this TActor actor) 
    { 
     // obviously this doesn't work either 
    } 
} 
+4

「不會編譯」是不是由編譯器提供實際的錯誤信息不太有用。 – 2013-02-25 21:56:27

+0

非常真實。對於那個很抱歉。錯誤是未知的參數(無論哪個不在那裏)。 – 2013-02-25 22:14:40

回答

3

您的擴展方法都只是缺少增加必要的通用參數:

public static class RunExtensions 
{ 
    public static TRun Run<TRun, TActor, TTarget>(this TRun map) 
     where TRun : Run<TActor, TTarget> 
    { 
     return map; 
    } 

    public static Run<TActor, TTarget> Run<TActor, TTarget>(this TActor actor) 
    { 
     return new Run<TActor, TTarget>(actor); 
    } 
} 
+0

這是我嘗試的第一件事。但是,這樣做會使擴展方法無法推斷類型,產生一個像pete.Run ()的方法調用。關閉(); ...這完全無法實現我正在嘗試執行的操作。這可能是我想做的事情根本不可能。 – 2013-02-25 22:22:53

+0

@JohnKraft那麼你期望它從哪裏推斷出它的類型呢?該方法無法知道目標應該是什麼類型。它不能僅僅從空氣中拉出來。 – Servy 2013-02-25 23:24:55

+2

沒錯。 :)正如我所說,這可能是不可能的,但我想我會問人比我更聰明。但是,從堆棧溢出問題的數量來看,這似乎是一個相當常見的問題,這些問題涉及從實例中獲取類名傳遞給泛型方法。 – 2013-02-26 02:46:29