2011-10-20 21 views
4
class Test 
{ 
    public delegate void FruitDelegate(Fruit f); 

    public void Notify<T>(Action<T> del) where T : Fruit 
    { 
     FruitDelegate f = del; // Cannot implicitly convert type 'Action<T>' to 'FruitDelegate 
    } 
} 

水果是空的類。這兩位代表都有相同的簽名。如何將動作轉換爲相同簽名的已定義委託?

我似乎無法得到任何這種工作。如果我解釋我正在嘗試做的事情(提供一些上下文),可能會有所幫助。

我想創建一個具有提供類型和方法回調(如上例)的泛型靜態方法的類。

我遇到的問題是委託包含一個參數,我不想在方法回調中強制轉換它。例如,我想這樣的:

public void SomeMethod() 
{ 
    Test.Notify<Apple>(AppleHandler); 
} 

private void AppleHandler(Apple apple) 
{ 

} 

取而代之的是:

public void SomeMethod() 
{ 
    Test.Notify<Apple>(AppleHandler); 
} 

private void AppleHandler(Fruit fruit) 
{ 
    Apple apple = (Apple)fruit; 
} 

是這種事情可能嗎?一直在努力了幾個小時沒有太多的運氣=/

回答

6

這是你想要的嗎?

static void Main(string[] args) 
{ 

    Program p = new Program(); 
    p.SomeMethod(); 
} 

public class Fruit 
{ } 

public class Apple : Fruit { } 

public delegate void FruitDelegate<in T>(T f) where T : Fruit; 

class Test 
{ 
    public static void Notify<T>(FruitDelegate<T> del) 
     where T : Fruit, new() 
    { 
     T t = new T(); 
     del.DynamicInvoke(t); 
    } 
} 

private void AppleHandler(Apple apple) 
{ 
    Console.WriteLine(apple.GetType().FullName); 
} 

public void SomeMethod() 
{ 
    FruitDelegate<Apple> del = new FruitDelegate<Apple>(AppleHandler); 
    Test.Notify<Apple>(del); 
} 
+0

哇!魔法!完美的作品。我必須盯着這一段時間。將此移至頂端。 –

2

有很好的理由,你不能這樣做。假設你的方法的其餘部分是:

class Test 
{ 
    public delegate void FruitDelegate(Fruit f); 

    public void Notify<T>(Action<T> del) where T : Fruit 
    { 
     FruitDelegate f = del; 
     f(new Banana()); //should be legal, but del may be Action<Apple> 
    } 
} 

這絕對不行,所以編譯器在這裏是正確的。

1

這樣的事情呢?

public void Notify<T>(Action<T> del) where T : Fruit 
{ 
    FruitDelegate f = fruit => del((T)fruit); 
} 

FruitDelegate實例,調用時,如果說,一個AppleHandlerBanana參數調用會拋出一個InvalidCastException。

+0

謝謝,這工作。 –

相關問題