相当于C#中Java的匿名类?

bkj*_*vbx 17 c# java

我试图将用java编写的SDK移植到C#.

在这个软件中有许多"处理程序"接口,有几种方法(例如:attemptSomethingHandlersuccess()几种不同的故障方法).然后在调用类中匿名实现和实例化该接口,并将其传递给类的attemptSomething方法SomethingModel.这是一个异步方法,有几个地方可能会失败或调用另一个方法(传递处理程序).这样,匿名实现attemptSomethingHandler可以在调用的类中引用私有方法attemptSomething.

在C#中,不可能匿名实现接口.我可以显式地实现一个新类,但是这个实现对于这个调用类来说是唯一的,而不是用于其他任何东西.更重要的是,我无法访问调用类中的私有方法,这是我需要的,也不想公开.

基本上,我需要根据SomethingModel类方法中发生的事情从调用类中运行不同的代码.

我一直在阅读代理,但这需要传递尽可能多的委托,因为处理程序界面中有方法(据我所知).在C#中执行此操作的适当方法是什么?我觉得我错过了一个非常常见的编程策略.必须有一种简单,干净的方式来构建和解决这个问题.

GvS*_*GvS 14

使用代表:

 void AttemptSomethingAsync(Action onSuccess, Action<string> onError1, Action onError2 = null) {
     // ...
 }

 // Call it using:

 AttemptSomethingAsync(onSuccess: () => { Yes(); }, onError1: (msg) => { OhNo(msg); });
Run Code Online (Sandbox Code Playgroud)

或者,使用课程

 class AttemptSomethingHandler {
     Action OnSuccess;
     Action<string> OnError1;
     Action OnError2;
 }

 void AttemptSomethingAsync(AttemptSomethingHandler handler) {
     // ...
 }

 // And you call it like
 AttemptSomethingAsync(new AttemptSomethingHandler() {
       OnSuccess = () => { Yes() };
 }); 
Run Code Online (Sandbox Code Playgroud)

或事件

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() {
}
Run Code Online (Sandbox Code Playgroud)


Dan*_*try 10

在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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在MyClass可以创建一个MyInterface实现的实例IMyInterface.正如评论家所提到的,MyInterface可以访问成员MyClass(尽管你肯定想尝试并坚持使用两种类型的公共可访问成员).

这封装了"匿名"类(在这里使用Java术语使其更简单)并且还意味着您可能潜在地返回MyInterface,IMyInterface而其余的软件将更加明智.这实际上是一些抽象工厂模式的工作方式.


基本上,我需要根据SomethingModel类方法中发生的事情从调用类中运行不同的代码.

这种气味很重.噢亲爱的!

听起来像你的特定问题可以使用重构.在C#中,您可以使用事件来解决此问题(注意:可以,但不应该).只需为您的方法的每个"分支"点设置一个事件.但是,我必须说,这确实使您的解决方案更难以设想和维护.

但是我建议你以一种不需要像这样的重型耦合的方式构建你的解决方案.

您也可以尝试使用Pipeline模型,但我不确定如何自己实现.我知道jetty(或者它是Netty?JBOSS的NIO for Java)当然使用了类似的模型.

您可能会发现抛出一些单元测试以测试您的类的预期功能将使您更容易构建您的解决方案(TDD).