簡體   English   中英

使用C#的匿名接口實現

[英]Anonymous interface implementation using C#

我有一些界面:

interface IServerListener
{
    void onServerStarted();
    void onSessionStarted();
    void onSessionCompleted(List<string> data);
}

還有一些方法,該方法獲取該接口的實例以執行方法:

public void start(IServerListener listener)
{
    IPEndPoint hostPoint = new IPEndPoint(IPAddress.Parse(getLocalHost()), PORT);
    serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    serverSocket.Bind(hostPoint);
    serverSocket.Listen(5);

    listener.onServerStarted(); //Calling

    while(true)...
}

當我從主表單類執行此方法(開始)時 ,我想將實現此接口的匿名類完全傳遞給參數,以便可以使用表單元素:

private void Form1_Load(object sender, EventArgs e)
{
    server = new Server();
    server.start(new IServerListener()
    {
        void onServerStarted()
        {
            rtxtOutput.AppendText("Started... ");
        }

        void onSessionCompleted(List<string> data)
        {
            rtxtOutput.AppendText("Session completed: " + String.Join(", ", data));
        }

        void onSessionStarted()
        {
            rtxtOutput.AppendText("New session started... ");
        }
    });
}

但是我不能像用Java那樣做。 我收到以下消息:

Cannot create an instance of the abstract class or interface 'IServerListener'

因此,我嘗試創建單獨的類來實現此接口,並且已經在那里執行我需要的操作。 但是我無法從那里訪問使用表單元素:

private class AnonymousIServerListener : IServerListener
{
    public void onServerStarted()
    {
        rtxtOutput.AppendText("Started... ");
        //The name 'rtxtOutput' does not exist in the current context
    }

    public void onSessionCompleted(List<string> data)
    {
        rtxtOutput.AppendText("Session completed: " + String.Join(", ", data));
        //The name 'rtxtOutput' does not exist in the current context
    }

    public void onSessionStarted()
    {
        rtxtOutput.AppendText("New session started... ");
        //The name 'rtxtOutput' does not exist in the current context
    }
}

請告訴我在沒有拐杖的情況下該怎么辦。 通常可以在C#中使用匿名類嗎? 如果沒有,在這種情況下該怎么辦?

提前致謝。 問候...

為什么不為此使用Action呢?

private void Form1_Load(object sender, EventArgs e)
{
    server = new Server();
    server.start(new ServerListener()
        { OnServerStarted = () => rtxtOutput.AppendText("Started... ")
        , OnSessionCompleted = data =>
            {
                rtxtOutput.AppendText("Session completed: " + String.Join(", ", data));
            }
        , OnSessionStarted = () => rtxtOutput.AppendText("New session started... ")
        )
    );
}

ServerListener

public class ServerListener : IServerListener
{
    void IServerListener.onServerStarted() => OnServerStarted?.Invoke();
    void IServerListener.onSessionStarted() => OnSessionStarted?.Invoke();
    void IServerListener.onSessionCompleted(List<string> data) => OnSessionCompleted?.Invoke(data);

    public Action OnServerStarted { get; set; }

    public Action<List<string>> OnSessionCompleted { get; set; }

    public Action OnSessionStarted { get; set; }
}

在這里, ServerListener只是充當連接各個點的中間件。 它本身不做任何事情。

這與匿名類型無關。 您想將AnonymousIServerListener與表單分離。 正因為如此,因為否則您將無法在沒有包含TextBox rtxtOutputForm1實例的情況下實例化AnonymousIServerListener

相反,例如,您希望從監聽器引發一個事件。 給您的界面一個事件:

public interface IServerListener
{
    event EventHandler<LogEventArgs> Log;

    // ...
}

定義EventArgs:

public class LogEventArgs : EventArgs
{
    public string LogText { get; }

    public LogEventArgs(string logText)
    {
        LogText = logText;
    }
}

然后將其添加到您的監聽器中:

public class AnonymousIServerListener : IServerListener
{
    public event EventHandler<LogEventArgs> Log = delegate { };

    public void OnServerStarted()
    {
        Log.Invoke(new LogEventArgs("Started... "));
    }

    public void OnSessionCompleted(List<string> data)
    {
        Log.Invoke(new LogEventArgs("Session completed: " + String.Join(", ", data)));
    }

    public void OnSessionStarted()
    {
        Log.Invoke(new LogEventArgs("New session started... "));
    }
}

最后,在實例化AnonymousIServerListener的類中訂閱您的事件:

private void Form1_Load(object sender, EventArgs e)
{
    server = new Server();

    IServerListener listener = new AnonymousIServerListener();

    listener.Log += (e) => rtxtOutput.AppendText(e.LogText);

    server.start(listener);
}

但是現在,當Form1_Load返回時,您將得到一個懸掛的引用,並與Log事件訂閱綁定在一起。 您將永遠無法取消訂閱,而在應用程序的剩余生命周期中,讓listener存活狀態。

暫無
暫無

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

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