汪...好的,请允许我做一些概括:
在Java中,您需要一种传递函数的方式。Java本身不支持作为一等公民的函数,这是实现匿名类的原因之一——打包的函数组,可以内联声明并作为接口传递给方法/其他类,然后调用这些函数。
在C#中,函数是一等公民,可以声明为Delegates
、Func<>
或Action<>
。让我们进行一些比较(某种程度上):
一些类似于Java的结构(我的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
{
public delegate void HandlerForBarEvent(object sender, EventArgs args);
public event HandlerForBarEvent BarEvent;
public void CallBar()
{
BarEvent(this, new EventArgs());
}
}
public void Main(string[] args)
{
var foo = new Foo();
foo.BarEvent += (sender, args) =>
{
}
foo.CallBar();
}
请注意,我们也可以将其分配给具有相同“形状”的内容:
public void MyHandler(object sender, EventArgs args)
{
}
public void Main(string[] args)
{
var foo = new Foo();
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()
{
foreach(var evt in eventList)
{
evt.Execute();
}
}