繁体   English   中英

等效于 C# 中的 Java 匿名类?

[英]Equivalent of Java's anonymous class in C#?

我正在尝试将用 Java 编写的 SDK 移植到 C#。

在这个软件中,有许多“处理程序”接口,有几种方法(例如: attemptSomethingHandlersuccess()和几种不同的失败方法)。 然后在调用类中匿名实现和实例化该接口,并传递给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 }

然而,这些不能在其中放置方法,只能通过使用objectdynamic传递给方法(因为它们在编译时没有类型,它们由编译器 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM