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