[英]Equivalent of Java's anonymous class in C#?
我正在尝试将用 Java 编写的 SDK 移植到 C#。
在这个软件中,有许多“处理程序”接口,有几种方法(例如: attemptSomethingHandler
和success()
和几种不同的失败方法)。 然后在调用类中匿名实现和实例化该接口,并传递给SomethingModel
类的attemptSomething
方法。 这是一个异步方法,有几个地方可能会失败或调用另一个方法(传递处理程序)。 这样, attemptSomethingHandler
的匿名实现就可以引用调用attemptSomething
的类中的私有方法。
在 C# 中,不可能匿名实现接口。 我可以显式地实现一个新类,但是这个实现对于这个调用类来说是唯一的,不用于其他任何东西。 更重要的是,我将无法访问调用类中的私有方法,而我需要且不想公开这些方法。
基本上,我需要根据SomethingModel
类方法中发生的情况从调用类运行不同的代码。
我一直在阅读委托,但这需要传递与处理程序接口中的方法一样多的委托(据我所知)。 在 C# 中执行此操作的适当方法是什么? 我觉得我错过了一个非常常见的编程策略。 必须有一种简单、干净的方法来构建和解决这个问题。
使用委托:
void AttemptSomethingAsync(Action onSuccess, Action<string> onError1, Action onError2 = null) {
// ...
}
// Call it using:
AttemptSomethingAsync(onSuccess: () => { Yes(); }, onError1: (msg) => { OhNo(msg); });
或者,使用类
class AttemptSomethingHandler {
Action OnSuccess;
Action<string> OnError1;
Action OnError2;
}
void AttemptSomethingAsync(AttemptSomethingHandler handler) {
// ...
}
// And you call it like
AttemptSomethingAsync(new AttemptSomethingHandler() {
OnSuccess = () => { Yes() };
});
或活动
public delegate void SuccessHandler();
public delegate void ErrorHandler(string msg);
class SomethingModel {
public event SuccessHandler OnSuccess;
public event ErrorHandler OnError1;
public void AttemptSomethingAsync() {
// ...
}
}
// Use it like
var model = new SomethingModel();
model.OnSuccess += Yes;
model.AttemptSomethingAsync();
private void Yes() {
}
在 C# 中,我们没有像 Java 本身那样的匿名类型。 您可以创建一个包含如下字段的匿名类型:
var myObject = new { Foo = "foo", Bar = 1, Quz = 4.2f }
然而,这些不能在其中放置方法,只能通过使用object
或dynamic
传递给方法(因为它们在编译时没有类型,它们由编译器 AFAIK 生成)
正如您所说,在 C# 中,我们使用委托或 lambdas。
如果我正确理解你的泡菜,你可以实现一个嵌套的私有类,如下所示:
interface IMyInterface
{
void Foo();
}
class MyClass
{
public void Bar()
{
var obj = new MyInterface();
obj.Foo();
}
private class MyInterface : IMyInterface
{
public void Foo()
{
// stuff
}
}
}
现在MyClass
可以创建一个实例MyInterface
,它实现IMyInterface
。 正如评论者所提到的, MyInterface
可以访问MyClass
成员(尽管您肯定想尝试并坚持使用这两种类型的可公开访问的成员)。
这种封装的“匿名”类(使用Java术语在这里,使其更简单),也意味着你可能会返回MyInterface
作为IMyInterface
和软件的其余部分将是毫无收获。 这实际上是一些抽象工厂模式的工作方式。
基本上,我需要根据SomethingModel 类方法中发生的情况从调用类运行不同的代码。
这闻起来有重耦合的味道。 哦亲爱的!
在我看来,您的特定问题可以使用重构。 在 C# 中,您可以使用事件来解决这个问题(注意:可以,不应该)。 只需为您的方法的每个“分支”点设置一个事件。 但是我必须说,这确实使您的解决方案更难设想和维护。
但是,我建议您以一种不需要如此繁重的耦合的方式构建您的解决方案。
您也可以尝试使用管道模型,但我不确定如何自己实现。 我知道码头(或者是 Netty?JBOSS 的 Java 版 NIO)肯定使用了类似的模型。
您可能会发现,为了测试类的预期功能而放弃一些单元测试将使构建解决方案 (TDD) 变得更加容易。
您可以使用嵌套类来模拟匿名类,但为了以与 Java 相同的方式使用嵌套类,您需要传递对外部类的引用。 在 Java 中,默认情况下所有嵌套和匿名类都有这个,只有静态类没有。
interface IMyInterface
{
void Foo();
}
class MyClass
{
public void Bar()
{
IMyInterface obj = new AnonymousAnalog(this);
obj.Foo();
}
private class AnonymousAnalog : IMyInterface
{
public void Foo(MyClass outerThis)
{
outerThis.privateFieldOnOuter;
outerThis.PrivateMethodOnOuter();
}
}
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.