2016-11-20 84 views
3

從回調的角度來看,當我知道myDelegate.Target包含對其所包含方法的類的引用時,我面臨一種奇怪的情況。 (我搜索它SO,但我原諒,如果我錯過了一些線程已經回答這個問題)如何確保委託實例引用

例如

public delegate void TravePlanDelegate(); 

public class Traveller 
{ 
    //Papa is planing a tour, along with Mama 
    public void Planner() 
    { 
     //Asking me (delegate) to hold a letter about PlanA's detail 
     TravelPlanDelegate myPlan = PlanA; 
     //Sending me to TravelAgency office with letter 
     new TravelAgency().ExecuteTravelPlan(myPlan); 
    } 
    public void PlanA() 
    { 
     //Papa's open plan with Mama 
     Console.WriteLine("First Berline, then New Yark and finally Lahore"); 
    } 
    public void PlanB() 
    { 
     //Papa's secret plan 
     Console.WriteLine("First Dubai, and then Lahore"); 
    } 
} 

public class TravelAgency 
{ 
    public void ExecuteTravelPlan(TravePlanDelegate tp) 
    { 
     Traveller traveller = (Traveller)tp.Target; 
     //Here it should execute plan 
     //tp.Target - A reference to Traveler class, which can lead travel 
     //agency to Papa's secret plan (And exposes it to Mama) 
    } 
} 

在這個例子中,旅行社可以獲取有關爸爸的祕密計劃從代表的信息了。我是否正確地獲得委託概念或錯過了什麼?

+0

在您的過程中是否存在潛在的敵對.NET代碼?或者你想防止泄漏的API內部? – usr

+0

我想使用像TravelAgency這樣的圖書館,但我懷疑他們可以進入我自己的圖書館的細節。 – Lali

回答

2

你的假設是正確的。不幸的是,不管你怎樣「封裝」你的對象,都必須在某處引用它,否則就不可能調用它的實例方法。

由於某種對策,可以代理的方法調用lambda表達式:

TravelPlanDelegate myPlan = (args) =>PlanA(args); 

這使得它不太可能任何惡意代碼會試圖進行一些生病的預期操作的代碼,因爲事先知道你的代碼如何看起來並不能幫助它完成任何事情。

請注意,這不能確保一件事情,因爲生成的委託仍然具有一個Target屬性,該對象持有對您的引用。

足夠聰明的餅乾仍然可以將反射應用到生成的類並獲取對象的引用。

結論:

只消耗代碼你信任 - 這沒有多少在今天的開源驅動的世界的問題。

+0

Lembda表達式是一種引用委託功能的方法。這對維護隱私沒有幫助。如果我是一個圖書館建設者,或者在另一端使用那個庫,能有更好的技術嗎? – Lali

+1

Lambda表達式不是將委託引用到函數的方式 - 它使用匿名方法創建匿名對象。這個類將有一個隨機名稱,並且將被調用的方法將具有一個隨機名稱。請注意,由於我在第一段中指定的推理,所以可能沒有辦法解決這個問題。 –

+0

是的,你是對的@Perry。實際上,我的評論「Lembda表達式是一種引用委託功能的方式」與上面的答案有關。我遵循你爲此感謝的理念。 – Lali