如何在 C# 中使用匿名类重新实现 Java 侦听器
Posted
技术标签:
【中文标题】如何在 C# 中使用匿名类重新实现 Java 侦听器【英文标题】:How to reimplement Java listeners with anonymous classes in C# 【发布时间】:2014-09-20 15:41:29 【问题描述】:我正在尝试在 C# 中复制我的 Java 代码,我想知道如何在 C# 中复制此 Java 功能。
Util.java
public class Util
public void function(String s, final SetAvailabilityStatusListener setStatusListener)
// ....
public static interface SetAvailabilityStatusListener
public void setAvailabilityStatus(Status status);
Activity.java
public class Activity
public void anotherFunction()
util.function("name", new SetAvailabilityStatus()
@Override
public void setAvailabilityStatus(Status status)
loginSetAvailabilityStatus(status);
【问题讨论】:
那究竟是哪个 Java 功能? C# Java-like inline extension of classes?的可能重复 【参考方案1】:使用委托。它们用于 C# 而不是实现接口的 Java 匿名类。
public class Util
public void Function(String s, Action<Status> setStatusListener)
// ....
setStatusListener("myStatus");
public class Activity
private Util util = new Util();
public void AnotherFunction()
util.Function("name", status => LoginSetAvailabilityStatus(status));
public void LoginSetAvailabilityStatus(string status)
//do something with status
【讨论】:
【参考方案2】:我找不到合适的副本,所以:
1. C# 没有像 Java 那样的匿名类,但没有人阻止您手动创建所需的侦听器类
public class Util
public void Function(String s, ISetAvailabilityStatusListener setStatusListener)
// ....
public interface ISetAvailabilityStatusListener
public void SetAvailabilityStatus(Status status);
public class Activity
private class MySetAvailabilityStatusListener: Util.ISetAvailabilityStatusListener
public void SetAvailabilityStatus(Status status)
// do your handling, but nested classes have some differences with anonymous Java classes, so it may require additional infrastructure.
public void AnotherFunction()
utilObj.Function("name",
new MySetAvailabilityStatusListener())
就是所谓的observer design pattern(只是没有注销方法!!)。
2. 正如@AndreySarafanov 已经建议的那样,您可以使用Action Delegates 和lambda expressions:
public class Util
public void Function(String s, Action<Status> statusChangeListener)
// ....
public class Activity
public void AnotherFunction()
utilObj.Function("name",
(status) =>
loginSetAvailabilityStatus(status);
3. C# 有另一种更简单的机制来处理事件处理(订阅)机制 - events and delegates
public class StatusEventArgs : EventArgs
//...
public class Util
public void SomeFunction()
// ....
if (this.OnAvailabilityChanged != null)
OnAvailabilityChanged(this, new StatusEventArgs(status));
public event EventHandler<StatusEventArgs> OnAvailabilityChanged
public class Activity
public void AvailabilityStatusChangedHandler(object sender, EventArgs<Status> eventArgs)
public void AnotherFunction()
utilObj.OnAvailabilityChanged += this.AvailabilityStatusChangedHandler;
它不允许你将 name 属性与事件处理程序相关联,你可以通过特殊的注册方法来克服它,但它会降低事件的可用性,所以你应该坚持另一种解决方案。
【讨论】:
我采用了@AndreySarafanov 提供的解决方案,但我相信您分享的信息对我在这个项目中的推进很有用。非常感谢 嗨。经过一番挣扎,我发现您的第三种方法最适合我的用例。但是当我使用App.Current.Resources["ResourceName"]
时,它会给出“无效的跨线程访问。”错误。我实际上是从 AsyncCallback 函数调用它。 public void UserAvailabilityCallback(IAsyncResult ar)
。据我所知,这在单独的线程上运行。你能建议一个修复吗?如果我在某处做错了,请纠正我。我正在使用Deployment.Current.Dispatcher
来解决这个问题。可以做其他事情来代替这个吗?
@PratPor 这是另一个与此问题没有直接关系的问题,因此您可能应该将其作为一个全新的问题提出 - 这个问题已经达到了它的目标。请阅读***.com/questions/8240490/…,然后再询问以更好地了解可能的问题和解决方案。
我认为第一个选项是一种更有用的方法,因为它可以更好地处理多个接口方法的情况,并且还允许您维护从 Java 到 C# 的接口(委托不能代替接口一般)。
@DaveDoknjas 是的,代表可能有点被嘲笑地称为穷人的观察者模式。它们是 UI 事件处理(在一个 UI 元素内)的有效解决方案,但对于更复杂的事情,您最终会使用更复杂的解决方案。以上是关于如何在 C# 中使用匿名类重新实现 Java 侦听器的主要内容,如果未能解决你的问题,请参考以下文章
java中常用APIScanner类匿名对象Random类ArrayList类对象数组