C#相当于创建实现接口的匿名类

我最近开始使用C#,我想找到一个等效的方法。 我不知道这叫什么,所以我只会通过代码向您展示。

使用Java,我能够创建如下界面:

public interface Event { public void execute(); } 

并在方法的参数中传递此接口,如下所示:

 public class TestEvent { ArrayList eventList = new ArrayList(); 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本身并不支持作为一等公民的function,这也是实现匿名类的一个原因 – 打包的函数组可以内联声明并作为接口传递给方法/其他类,然后调用这些函数。

在C#中,函数是一等公民,可以声明为DelegatesFunc<>sAction<>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 returns42 = () => 42; Func amIPretty = name => name == "jerkimball"; Action 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来定义线程所做的事情,如果内存服务(即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 eventList = new List(); 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 GetValue { get; set; } } 

然后,您可以创建它:

 var anon = new Delegates { Event = () => { ... }, GetValue = () => "Value" }