[英]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 rtxtOutput
的Form1
實例的情況下實例化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.