在Java中,这是正常的:
public class Test {
public static void main(String[] args) throws Exception {
new Test().doWork(new Callback() { // implementing class
@Override
public void call() {
System.out.println("callback called");
}
});
}
public void doWork(Callback callback) {
System.out.println("doing work");
callback.call();
}
public interface Callback {
void call();
}
}
我想知道C#中是否存在等价?我在C#中进行了实验,但在doWork()函数之后有问题实例化的新接口。是因为在JAVA中你可以创建一个接口的instacne而C#你不能吗?
答案 0 :(得分:1)
不一样,但类似的方法(传递委托)将是:
DoWork(() => Console.WriteLine("callback called"));
void DoWork(Action callback)
{
Console.WriteLine("doing work");
callback();
}
修改强>
尤其是当我处理具有OnSuccess,OnError的Web服务时。
DoWork(new MyResult() {
OnSuccess = () => Console.WriteLine("Success"),
OnError = ()=>Console.WriteLine("Error") }
);
public class MyResult
{
public Action OnSuccess { set; get; }
public Action OnError { set; get; }
}
void DoWork(MyResult callback)
{
Console.WriteLine("doing work");
callback.OnSuccess();
}
答案 1 :(得分:0)
Java相当简洁的'内联实现'/'内联类定义'(您已在上面说明)不是C#的一部分。
你可以继续实现监听器接口/类并将它们传递给对象,这实际上是同样的事情 - 但是,这可能非常快速,并且通常你真的只想要无论如何都要提供一个回调。
C#有两个有用的工具,可以让生活更轻松:
<强>代表强>
在查看事件之前理解代表是有意义的。 Delegate是一种将方法作为变量或参数传递的简洁方法。
您可以定义委托类型(如果您愿意):
public delegate void AMethodThatHandlesAnInteger(int theInt);
然后将它们用作方法的参数:
public void doStuffAndThenCallADelegate(AMethodThatHandlesAnInteger theDelegate)
{
...
theDelegate(4);
}
或者,通常情况下,使用已存在的预定义委托之一更容易:
public void doStuffAndThenCallADelegate(Action<int> theDelegate)
{
...
theDelegate(4);
}
Delegates can be generic - 这使它们成为一个非常强大的工具。
有许多delegates defined by the framework,(由方便的Q&amp; A链接到列出)。在简单的情况下,我经常发现自己使用Action
(void方法,不带参数)和Action<Something>
(void方法,只接受一个参数)。
Func<Something,Else>
允许返回类型,从那里变得更有趣! Actions和Funcs允许0-4个参数(不包括Func的返回类型)。
<强>事件强>
虽然可以使用委托构建自己的模式来监视对象更改,但C#更进一步为您提供现成的事件......
Events是一个非常方便的方法,可以让对象整理'handler'委托方法,然后用一组参数调用它们。
首先定义'handler'方法的委托类型:
public delegate void StuffHappenedHandler(int stuffs, string summary);
然后,通过定义公共事件,您可以为委托的注册/注销创建一个可到达的字段。我有时会在事件前面添加'On' - 这是代码样式的问题:
public event StuffHappenedHandler OnStuff;
希望监视此事件的对象需要一个与StuffHappenedHandler
委托类型签名匹配的方法:
public void MonitoredObjectStuffHandler(int howMany, string summary)
{
...
}
现在它可以使用OnStuff
事件注册该方法:
monitoredObject.OnStuff += ObjectStuffHandler;
要从事件中取消注册委托方法,它就是这么简单:
monitoredObject.OnStuff -= ObjectStuffHandler;
在通知可能正在侦听的对象时,检查null事件非常重要。如果没有注册,该事件将为null:
if (OnStuff != null)
OnStuff(4, "four things");
答案 2 :(得分:0)
如果您真的想在C#中执行与此类似的操作,可以使用Moq这是一个单元测试框架(通常仅用于单元测试,而不是生产代码)。我不建议实际执行此操作,因为其他人建议C#具有替代模式,以更好的方式实现您尝试的相同目标,例如Delegates或async / await。但是,通过Moq可以创建接口实例,这对于C#中的单元测试非常有用(特别是如果你使用IoC)。
public class Test
{
public static int Main(string[] args)
{
var mockCallback = new Mock<ICallback>();
mockCallback.Setup(t=>t.Call()).Callback(() =>
{
Console.WriteLine("callback called");
});
new Test().doWork(mockCallback.Object);
}
public void DoWork(ICallback callback)
{
Console.WriteLine("doing work");
callback.Call();
}
}
public interface ICallback
{
void Call();
}