[英]C# equivalent of creating anonymous class that implements an interface
我最近開始使用C#,我想找到一個等效的方法。 我不知道這叫什么,所以我只會通過代碼向您展示。
使用Java,我能夠創建如下界面:
public interface Event {
public void execute();
}
並在方法的參數中傳遞此接口,如下所示:
public class TestEvent {
ArrayList<Event> eventList = new ArrayList<Event>();
public void addEvent(Event event){
eventList.add(event);
}
public void simulateEvent(){
addEvent(new Event() {
public void execute(){
//functionality
}
} );
}
public void processEvents(){
for(Event event : eventList)
eventList.execute();
}
}
編輯 :我的問題是來自TestEvent
類的simulatEvent
方法,如果C#可以執行此類操作。
我想知道是否有辦法用C#做一些類似的事情(在simulateEvent
方法中實例化接口)以及實際調用它的方法。 謝謝!
Woof ......好的,請允許我概括一下:
所以在Java中,你需要一種傳遞函數的方法。 Java本身並不支持作為一等公民的功能,這是實現匿名類的一個原因 - 打包的函數組,可以內聯聲明並傳遞給接口,然后傳遞給方法/其他類,然后調用這些函數。
在C#中,函數是一等公民,可以聲明為Delegates
, Func<>s
或Action<>s
。 讓我們嘗試比較(各種):
某種Java-y構造(我的Java相當老,所以請耐心等待):
public interface IDoSomething {
public int Return42();
public bool AmIPrettyOrNot(string name);
public void Foo();
}
public void Main(String[] args) {
DoStuff(new IDoSomething() {
public int Return42() { return 42; }
public bool AmIPrettyOrNot(string name) { return name == "jerkimball"; }
public bool Foo(int x) { ... }
});
}
public void DoStuff(IDoSomething something) { ... }
C#中的(非常粗略)相當於:
public void Main(string[] args)
{
Func<int> returns42 = () => 42;
Func<string,bool> amIPretty = name => name == "jerkimball";
Action<int> foo = x => {};
}
現在,正如其他人所提到的,在處理事件時,您通常會在Java端看到這種模式 - 同樣在C#端:
public class Foo
{
// define the shape of our event handler
public delegate void HandlerForBarEvent(object sender, EventArgs args);
// declare our event
public event HandlerForBarEvent BarEvent;
public void CallBar()
{
// omitted: check for null or set a default handler
BarEvent(this, new EventArgs());
}
}
public void Main(string[] args)
{
var foo = new Foo();
// declare the handler inline using lambda syntax
foo.BarEvent += (sender, args) =>
{
// do something with sender/args
}
foo.CallBar();
}
請注意,我們也可以給它一些具有相同“形狀”的東西:
public void MyHandler(object sender, EventArgs args)
{
// do stuff
}
public void Main(string[] args)
{
var foo = new Foo();
// that method above is the same "shape" as HandlerForBarEvent
foo.BarEvent += MyHandler;
foo.CallBar();
}
但它也用於Java來定義Threads做什么,如果內存服務(即Runnable
) - 我們也可以在C#中做到這一點:
var thread = new Thread((Action)(() =>
{
// I'm the threads "run" method!
});
thread.Start();
現在,其他的東西 - 枚舉:
public void processEvents(){
for(Event event : eventList)
eventList.execute();
}
C#有相同的想法,只是用不同的方式調用:
public void processEvents()
{
// edit: derp, 'event' is a keyword, so I'm
// renaming this, since I won't get into why
// you could also use @event...
foreach(var evt in eventList)
{
evt.Execute();
}
}
編輯:看起來你的問題是關於匿名接口實現而不是事件。 您可以使用內置的Action
委托類型而不是Event
接口。
然后,您可以使用lambda表達式的Action
實例。 您的代碼如下所示:
public class TestEvent
{
List<Action> eventList = new List<Action>();
public void addEvent(Action event){
eventList.add(event);
}
public void simulateEvent(){
addEvent(() => {
});
}
public void processEvents(){
for(Action event : eventList)
event();
}
}
您可以使用delegate
語法而不是在simulateEvent
中使用() => { .. .}
ie delegate() { ... }
。
C#不支持匿名接口實現,因此如果您的接口有多個方法,那么您必須在某處定義一個具體的類。 根據用途,您可以讓此類包含您可以在創建時提供的委托屬性,例如
public class Delegates
{
public Action Event { get; set; }
public Func<string> GetValue { get; set; }
}
然后你可以創建它:
var anon = new Delegates
{
Event = () => { ... },
GetValue = () => "Value"
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.