呜呜……好吧,请允许我概括一下:
所以在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 中用于定义线程做什么,如果内存服务(即,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();
}
}