2011-03-11 81 views
3

我正在使用AssemblyResolve。這是我的代碼第一,然後我的問題如下:將自己的參數發送給事件處理程序?

var a = AppDomain.CurrentDomain; 
a.AssemblyResolve += new ResolveEventHandler(HandleIt); 

Private Assembly HandleIt(object sender, ResolveEventArgs args){ 
    //Does stuff, returns an assembly 
} 

因此,我將HandleIt添加到我的AssemblyResolve事件。我怎樣才能把它添加到該事件,並傳遞一個參數,它像:

a.AssemblyResolve += new ResolveEventHandler(HandleIt(AnArgument)); 

這是扔我了,因爲HandleIt接受參數,但是當它被添加到AssemblyResolve事件沒有被explicetly通過。我希望是這樣的:

a.AssemblyResolve += new ResolveEventHandler(HandleIt(aSender,someArgs)); 

所以,是的,我只是希望能夠將它添加到我的AssemblyResolve事件時,另外一個參數發送給我的HandleIt功能。

希望有道理,謝謝。

附錄:

if(aBool){ 
    a.AssemblyResolve += new ResolveEventHandler(HandleA); 
} 
else{ 
    a.AssemblyResolve += new ResolveEventHandler(HandleB); 
} 

HandleA(object sender, ResolveEventArgs args){ 
    Handle(true); 
} 
HandleB(object sender, ResolveEventArgs args){ 
    Handle(false); 
} 
Handle(bool isA){ 

} 

航班嗎

if(aBool){ 
    a.AssemblyResolve += (object s, ResolveEventArgs a) => Handle(s,a,true); 
} 
else{ 
    a.AssemblyResolve += (object s, ResolveEventArgs a) => Handle(s,a,false); 
} 

Handle(object sender, ResolveEventArgs args, bool isA){ 

} 
+0

你不需要的,如果(aBool)在lambda版本,你可以簡單地say'a.AssemblyResolve + =(對象S,ResolveEventArgs一)= >拉手(S,A,aBool);'或曾經的說法應該是什麼 – 2011-06-26 14:01:17

回答

7

當事件被觸發參數傳遞給方法,如果你要綁定額外的參數,你可以這樣做與lambdaexpression

var a = AppDomain.CurrentDomain; 
a.AssemblyResolve += (object s,ResolveEventArgs a) => HandleIt(s,a,someArgument); 

Private Assembly HandleIt(object sender, ResolveEventArgs args, SomeType arg){ 
    //Does stuff, returns an assembly 
} 

其中someArgument是你希望綁定值。

這實質上是使用lambdas來完成函數的部分應用。 C#不直接支持的東西,但在其他語言中很常見。部分應用程序與當前存在於諸如F#和Haskell之類的語言中的Currying關係非常密切(因爲該概念從Haskell Curry獲得它的名稱)以及各種其他函數式語言。它們在結果類型上有所不同。

它們都涉及到關閉(如上面的代碼的概念被稱爲),並在不支持部分應用程序或討好你可以使用閉包來完成類似的語言。但請注意,關閉與部分應用程序的不同之處在於會產生一些令人驚訝的錯誤。例如。

int i = 1; 
Func<int> f =() => i; 
i = 2; 

System.Console.WriteLine(f()); 

2打印到控制檯。因爲封閉件捕獲參考給一個變量不是所述變量的值。當關閉for循環的循環變量時,這是for循環中的常見錯誤。

+0

這是非常聰明的,謝謝你的提示。 – asawyer 2011-03-11 21:34:35

+0

投了票,而不是我的回答 – DaveShaw 2011-03-11 21:35:07

+0

這在手動觸發事件實現自己的目標沒有幫助。查看我答案中的更新。 – 2011-03-11 21:37:47

2

AppDomain.CurrentDomain將引發事件和傳遞參數,所述+ =行簡單地註冊一個處理程序來的情況下,參數將有沒有任何意義。

打個比方:

您註冊郵遞員您的地址,他deilivers向該地址發送郵件後。當您在郵局註冊時,您不會向他們發送您希望稍後交付給您的郵件!

+0

當然,我可以看到我的理解是更糟糕的,我認爲它是前。也許它甚至沒有意義,我想要做什麼,這是:我故意觸發AssemblyResolve選擇我自己的DLL在運行時加載。我想能夠說:通過傳遞一個參數到我的AssemblyResolve事件處理程序來加載這個或那個DLL。這會改變什麼嗎? – sooprise 2011-03-11 21:33:29

+0

看看符文FS的回答。另外,如果這是你想要做的,這應該是你的問題! – asawyer 2011-03-11 21:35:54

0

技術性更強一點:您正在爲事件註冊一個委託給您的方法。這不是對方法的調用。 這是一個有點類似於此:

Action<object, ResolveEventArgs> handleItDelegate = HandleIt; 

當事件被激活時,委託被調用。我的樣品的比喻是:

handleItDelegate(sender, eventArgs); 

UPDATE:
在一個評論,你澄清,你想達到什麼樣的:你要觸發事件,那麼您的組件加載。你不能這樣做,你認爲它的工作方式。要手動加載組件,只需這樣做,不需要事件。當運行時試圖解析引用的程序集,但找不到它時,調用該事件。

1

這是不可能的。 HandleIt在這種情況下是一個委託,具有匹配ResolveEventHandler

a.AssemblyResolve += new ResolveEventHandler(HandleIt); 

的簽名在此行中設置它只是告訴代碼時AssemblyResolve上升引發此AssemblyResolved活動將通過它的東西要執行什麼參數。你可以用你自己的參數重新引發另一個事件,並將其掛鉤到另一個處理程序(或者只是調用一個方法)。

編輯:或者,也許你可以用的Lamda的:○

+0

這是否是「最佳實踐」方法?我可以看到我可以通過lambda表達式混亂地添加參數。 – sooprise 2011-03-11 21:35:32

+0

可能不是。我贊成Lamda的回答。 – DaveShaw 2011-03-11 21:36:42

+0

這就是我過去爲這類問題所做的。那lambda的東西雖然很漂亮。 – asawyer 2011-03-11 21:37:43

相關問題