簡體   English   中英

用什么? 委托,事件或Func <T> ?

[英]What to use? delegate, event, or Func<T>?

我想為類庫中的對象提供“輸出”消息的能力,而不必擔心它是如何輸出的。 類庫可以在控制台應用程序,WinForm或WPF窗口應用程序或網頁中使用。

我最初決定使用委托來處理這個問題。 我使用類實現了這一點,但是當我試圖將委托放入一個固有的每個對象的接口時,編譯器不喜歡委托。

我發現我可以將代理移出界面然后能夠編譯但是我不確定這是否能完成我想要做的事情..它看起來像是一個kludge所以我想問你們是否有人有不同的想法來實現這一目標......

界面:

namespace Test
{
  using System;
  using System.Xml.Linq;

  public interface IAction
  {
    DisplayMessageDelegate DisplayMessage(string message);
    void Execute();
    XElement Serialize(XName elementName);
  }

  public delegate void DisplayMessageDelegate(string message);
}

從那里,我不知道如何實現這種行為:( 順便說一句,我知道這段代碼不會編譯......)

public class ActionClass1 : IAction
{
  // Other methods not shown...
  void Execute()
  {
    if (this.DisplayMessage != null)
    {
      this.DisplayMessage(“Hello”);
    }
  }
}

public class ConsoleClass
{
  ActionClass1 class1 = new ActionClass1();
  class1.DisplayMessage = { x =>  Console.WriteLine(x); };
}

public class WinFormClass
{
  ActionClass1 class1 = new ActionClass1();
  Class1.DisplayMessage = {x => DisplayTextBox.Text = x; };
}

如果你想要連接多個代理以響應對Execute的單個調用,我肯定會使用一個event 如果您只想連接單個操作,請使用ActionFunc委托。

對於您的示例,其中一個Action代理應該可以工作。 在您的情況下,它將是Action<string>因為您的委托采用字符串參數。 Action只是一個委托,它接受零個或多個參數並返回void。 看來你沒有返回任何東西,所以這就是我建議Action的原因。

如果您的委托需要返回某些內容,您只想使用Func<TResult> 之間的區別FuncActionFunc代表返回類型,和Action代表沒有。 這些代理中的任何一個都具有泛型版本,最多可以包含16個左右的參數。

如果您在委托上需要超過16個參數,則可能需要重新考慮設計:)

您可以使用Action<string>執行此Action<string>

您不希望使用Func<T> ,因為這是定義一個不帶參數但只返回Action<T>類型值的委托。另一方面, Action<T>是一個委托,它接受一個類型的參數T.

我建議嘗試:

public interface IAction
{
    Action<string> DisplayMessage { get; set; }

    void Execute();
    XElement Serialize(XName elementName);
}

完全實現此接口后,您可以通過以下方式使用它:

public class ConsoleClass
{
    public void SomeMethod()
    {
        ActionClass1 class1 = new ActionClass1();
        class1.DisplayMessage = x => Console.WriteLine(x);
    }
}

要么:

public class ConsoleClass
{
    public void SomeMethod()
    {
        ActionClass1 class1 = new ActionClass1();
        class1.DisplayMessage = this.Print;
    }

    private void Print(string message)
    {
        Console.WriteLine(message);
    }
}

你可以用事件做同樣的事情,但是,我會質疑這一點。 您的API正在描述應該發生的操作,而不是您正在響應的事件 - 因此,我不推薦事件。

您的界面定義錯誤。 您需要像這樣指定它:

namespace Test
{
  using System;
  using System.Xml.Linq;

  public interface IAction
  {
    DisplayMessageDelegate DisplayMessage { get; set; };
    void Execute();
    XElement Serialize(XName elementName);
  }

  public delegate void DisplayMessageDelegate(string message);
}

然后實現接口。

這里

DisplayMessageDelegate DisplayMessage(string message);

您描述接受字符串並返回DisplayMessageDelegate的方法。 使用

 event DisplayMessageDelegate DisplayMessage;

代替。

我個人認為你最好有一個抽象基類,它定義了一個名為DisplayMessage的抽象方法,然后通過從中派生來擴展該基類,以改變消息顯示方式的行為。

代替:

DisplayMessageDelegate DisplayMessage(string message);

做:

event Action<string> DisplayMessage;

然后按正常使用DisplayMessage,事件是委托。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM