Equivalent to Java anonymous class in C #?

I am trying to pass an SDK written in java to C #.

There are many handler interfaces with several methods in this software (for example: attemptSomethingHandler with success() and several different failure methods). This interface is then implemented and created anonymously inside the calling class and passed to the attemptSomething method of the SomethingModel class. This is an async method and has several places where it can fail, or calls another method (passing to the handler). Thus, the anonymous implementation of attemptSomethingHandler can refer to private methods in the class that calls attemptSomething .

In C #, it is not possible to anonymously implement an interface. I could explicitly implement the new class, but this implementation would be unique to this calling class and not used for anything else. More importantly, I would not be able to access the private methods in the calling class that I need and do not want to publish.

Basically, I need to run different code from the calling class, depending on what happens in the methods of the SomethingModel class.

I read delegates, but for this I would need to pass as many delegates as there are methods in the handler interface (as far as I can tell). What is the appropriate way to do this in C #? I feel that I am losing sight of a very general programming strategy. There simply should be a simple and understandable way of structuring and solving this problem.

+7
java c #
source share
3 answers

In C #, we do not have anonymous types like Java. You can create an anonymous type that contains the following fields:

var myObject = new { Foo = "foo", Bar = 1, Quz = 4.2f }

However, they cannot contain methods and can only go to methods using object or dynamic (since they have no type at compile time, they are generated by the AFAIK compiler)

Instead of C #, we use, as you said, delegates or lambdas.

If I understand your pickle correctly, you can implement a nested private class as follows:

 interface IMyInterface { void Foo(); } class MyClass { public void Bar() { var obj = new MyInterface(); obj.Foo(); } private class MyInterface : IMyInterface { public void Foo() { // stuff } } } 

Now MyClass can create an instance of MyInterface that implements IMyInterface . As commentators noted, MyInterface can refer to MyClass members (although you certainly want to try using publicly available members of both types).

This encapsulates an β€œanonymous” class (using Java terms here to simplify it), and also means that you could return MyInterface as IMyInterface , and the rest of the software would not be wiser. In fact, how some abstract factory patterns work.


Basically, I need to run different code from the calling class, depending on what happens in the methods of the SomethingModel class.

It smells of heavy grip. Oh dear!

It seems to me that your specific problem may use refactoring. In C #, you can use Events to solve this problem (note: Can, not should). Just specify an event for each "branch" of your method. However, I must say that this makes your decision harder to foresee and support.

However, I suggest you architect your solution in such a way that you do not need such a heavy connection.

You can also try using the Pipeline model, but I'm not sure how to implement it. I know that the pier (or is it Netty? NIO for Java from JBOSS), of course, used a similar model.

You may find that dropping some unit tests to test the expected functionality of your class will simplify archiving your solution (TDD).

+8
source share

Using delegates:

  void AttemptSomethingAsync(Action onSuccess, Action<string> onError1, Action onError2 = null) { // ... } // Call it using: AttemptSomethingAsync(onSuccess: () => { Yes(); }, onError1: (msg) => { OhNo(msg); }); 

Or using a class

  class AttemptSomethingHandler { Action OnSuccess; Action<string> OnError1; Action OnError2; } void AttemptSomethingAsync(AttemptSomethingHandler handler) { // ... } // And you call it like AttemptSomethingAsync(new AttemptSomethingHandler() { OnSuccess = () => { Yes() }; }); 

Or events

 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() { } 
+6
source share

You can use nested classes to mimic anonymous classes, but in order to use nested classes just like Java, you will need to pass a reference to the outer class. In Java, all nested and anonymous classes have this by default, and only static ones do not.

 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(); } } ... } 
+1
source share

All Articles