Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
相当于Java';C#中的匿名类?_Java_C# - Fatal编程技术网

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

相当于Java';C#中的匿名类?,java,c#,Java,C#,我正在尝试将一个用java编写的SDK移植到C 在该软件中,有许多具有多种方法的“处理程序”接口(例如:attemptSomethingHandlerwithsuccess()和几种不同的失败方法)。然后在调用类中匿名实现和实例化该接口,并将其传递给SomethingModel类的attemptSomething方法。这是一个异步方法,有几个地方可能会失败或调用另一个方法(传递处理程序)。这样,attemptSomethingHandler的匿名实现就可以引用调用attemptSomething

我正在尝试将一个用java编写的SDK移植到C

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

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

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

我一直在阅读委托,但这需要传递尽可能多的委托,因为处理程序接口中有很多方法(据我所知)。 用C#做这件事的合适方法是什么?我觉得我错过了一个非常常见的编程策略。必须有一种简单、干净的方法来构造和解决这个问题。

在C#中,我们没有像Java这样的匿名类型。您可以创建包含如下字段的匿名类型:

interface IMyInterface
{
    void Foo();
}

class MyClass
{
    public void Bar()
    {
        var obj = new MyInterface();
        obj.Foo();
    }

    private class MyInterface : IMyInterface
    {
        public void Foo()
        {
            // stuff
        }
    }
}
var myObject=new{Foo=“Foo”,Bar=1,Quz=4.2f}

但是,这些方法不能放在其中,只能通过使用
对象
动态
传递到方法中(因为它们在编译时没有类型,所以由编译器AFAIK生成)

相反,在C#中,正如您所说,我们使用委托或lambda

如果我正确理解了pickle,您可以实现一个嵌套的私有类,如下所示:

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#中,您可以使用事件来解决这个问题(注意:can,not should)。只需为方法的每个“分支”点设置一个事件。然而,我必须说,这确实使您的解决方案更难设想和维护

然而,我建议您以这样一种方式构建您的解决方案,即您不需要这样的重耦合

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

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

使用委托:

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

 // Call it using:

 AttemptSomethingAsync(onSuccess: () => { Yes(); }, onError1: (msg) => { OhNo(msg); });

您可以使用嵌套类来模拟匿名类,但是为了以与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();
        }
    }

    ...
}

也许值得用您正在尝试移植的java代码来说明您的问题,以及您迄今为止的尝试?您的问题不清楚,所以我现在还不知道,但是您可能想检查一下,您可以在内部类中实现接口。通过这种方式,您可以访问调用类的私有成员。听起来您几乎想要一个私有嵌套类。Java中的许多匿名类型都可以被C#中的事件或lambda所取代。“尽管您肯定希望尝试并坚持使用这两种类型的公共可访问成员“为什么”耦合。虽然我认为在这个实例中,它是一个私有嵌套类,但它是没有实际意义的。如果可以避免的话,我个人会尽量避免使用嵌套类中的私有方法——这不是私有的用途。我可能应该提到,我的意思是避免在嵌套类中使用私有方法,而不是避免使用内部/受保护方法。另外,我假设如果您将接口实现为嵌套类,那么您就不想从父类接触嵌套类的私有方法。谢谢您的回答。根据您使用嵌套私有类的示例:IMyInterface可能需要在不同的类中以不同的方式实现。因此,Foo()可能需要访问MyClass的实例和传递给Bar()的参数。但在其他地方,它可能需要其他参数等。听起来你是对的,我的解决方案需要进行重大重构。认为我可以保持与java实现相同的结构可能是愚蠢的:)听起来我确实可以使用事件。在某些情况下,这些事件必须由那些使用SDK的人来实现,这可能吗?如果您指的是Java SDK,恐怕互操作超出了我的能力范围。因为(几乎)没有理由使用匿名类@nicolas他们是XY问题的一个例子。唯一可接受的用途是
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();
        }
    }

    ...
}