9

I've recently started using C#, and I wanted to find an equivalent method to this. I do not know what this is called, so I will simply show you by code.

With Java, I was able to create an interface like so:

public interface Event {
    public void execute();
}

And pass this interface in a method's parameter like so:

public class TestEvent {
    ArrayList<Event> eventList = new ArrayList<Event>();

    public void addEvent(Event event){
        eventList.add(event);
    }

    public void simulateEvent(){
        addEvent(new Event() {
            public void execute(){
                //functionality
            }
        } );
    }

    public void processEvents(){
        for(Event event : eventList)
            eventList.execute();
    }
}

EDIT : My question is revolved on the simulatEvent method from the TestEvent class, and if such an action is possible with C#.

I wanted to know if there was a way to do something similar to this with C#, (instantiating the interface in the simulateEvent method) and what this is actually called. Thank you!

nawfal
  • 70,104
  • 56
  • 326
  • 368
user1606034
  • 113
  • 1
  • 5
  • If it's for event and event handling, see .. [Events in C#](http://msdn.microsoft.com/en-us/library/awbftdfh.aspx). This entire construct is done in a different, "C# fashion". You'll run into delegates (i.e. callback functions) and MulticastDelegate (i.e. how multiple event handlers are bound) in your reading. –  Mar 23 '13 at 00:07
  • That's an [anonymous class](http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html) and no, that doesn't work on interfaces in C#. – Tim Schmelter Mar 23 '13 at 00:10
  • Do you want to handle events or are you asking for the equivalent of instantiating an interface (in your simulateEvent code)? – ta.speot.is Mar 23 '13 at 00:11
  • http://stackoverflow.com/questions/191013/can-a-c-sharp-anonymous-class-implement-an-interface – ta.speot.is Mar 23 '13 at 00:12
  • BTW: I'm voting to close as "Not a Real Question". Please say/ask what you mean. The posted code has many constructs and doesn't isolate any particular problem/question. –  Mar 23 '13 at 00:12
  • @pst Sorry for not being specific! I have just changed the wording of the question. – user1606034 Mar 23 '13 at 00:33
  • @user1606034 Isolate the *specific* construct and remove the extra/unrelated code. I imagine the bit in question is really the `new Event() { .. }` bit? Also make sure the title is an accurate summary and doesn't use "this", which is both unclear and confusing. –  Mar 23 '13 at 00:35
  • Check out search results - http://stackoverflow.com/search?q=[c%23]+anonymous+interface+java , answer is No, but with options to mimic. – Alexei Levenkov Mar 23 '13 at 00:38

2 Answers2

6

Woof...ok, permit me to generalize a bit:

So in Java, you need a way to pass functions around. Java does not inherently support functions as first-class citizens, and this was one reason behind the implementation of anonymous classes - packaged groups of functions that can be declared inline and passed (as interfaces) to methods/other classes that will then call these functions.

In C#, functions are first-class citizens, and can be declared as either Delegates, Func<>s, or Action<>s. Let's try a comparison (of sorts):

Some sort of Java-y construct (my Java's fairly old, so bear with me):

public interface IDoSomething {
    public int Return42();
    public bool AmIPrettyOrNot(string name);
    public void Foo();
} 

public void Main(String[] args) {
    DoStuff(new IDoSomething() {
        public int Return42() { return 42; }
        public bool AmIPrettyOrNot(string name) { return name == "jerkimball"; }
        public bool Foo(int x) { ... }
    });
}

public void DoStuff(IDoSomething something) { ... }

The (very rough) equivalent of this in C# would be:

public void Main(string[] args)
{
    Func<int> returns42 = () => 42;
    Func<string,bool> amIPretty = name => name == "jerkimball";
    Action<int> foo = x => {};
}

Now, as others have mentioned, you usually see this pattern on the Java side when dealing with the handling of events - likewise on the C# side:

 public class Foo 
 {
     // define the shape of our event handler
     public delegate void HandlerForBarEvent(object sender, EventArgs args);
     // declare our event
     public event HandlerForBarEvent BarEvent;

     public void CallBar()
     {
         // omitted: check for null or set a default handler
         BarEvent(this, new EventArgs());
     }
 }    

 public void Main(string[] args)
 {
      var foo = new Foo();
      // declare the handler inline using lambda syntax
      foo.BarEvent += (sender, args) => 
      {
           // do something with sender/args
      }
      foo.CallBar();
 }

Note that we can also give it something with the same "shape":

 public void MyHandler(object sender, EventArgs args)
 {
     // do stuff
 }
 public void Main(string[] args)
 {
      var foo = new Foo();
      // that method above is the same "shape" as HandlerForBarEvent
      foo.BarEvent += MyHandler;
      foo.CallBar();
 }

But it's also used in Java to define what Threads do, if memory serves (i.e., Runnable) - and we can do this as well in C#:

var thread = new Thread((Action)(() => 
     {
         // I'm the threads "run" method!
     });
thread.Start();

Now, other stuff - enumeration:

public void processEvents(){
    for(Event event : eventList)
        eventList.execute();
}

C# has the same idea, just called differently:

public void processEvents()
{
    // edit: derp, 'event' is a keyword, so I'm
    // renaming this, since I won't get into why
    // you could also use @event...
    foreach(var evt in eventList)
    {
        evt.Execute();
    }
}
JerKimball
  • 16,584
  • 3
  • 43
  • 55
  • 1
    Well they're not really first-call citizens. They're more like second class citizens adopted from F# (Action, Func, Linq (monads), Lambdas). Delegates aren't really functions they're a special class used to reference functions. – Dustin Kingen Mar 23 '13 at 00:36
  • 3
    @Romoku Oh, you're just nit picking :) - yes, you are correct; don't ask how many times I've tried to beat the C# compiler type inference into submission during monadic declarations... – JerKimball Mar 23 '13 at 00:40
2

EDIT: It looks like your question is about anonymous interface implementations instead of events. You can use the built-in Action delegate type instead of your Event interface.

You can then Action instances using lambda expressions. Your code would look like:

public class TestEvent
{
    List<Action> eventList = new List<Action>();

    public void addEvent(Action event){
        eventList.add(event);
    }

    public void simulateEvent(){
        addEvent(() => {
        });
    }

    public void processEvents(){
        for(Action event : eventList)
            event();
    }
}

You can use the delegate syntax instead of using () => { .. .} i.e. delegate() { ... } in simulateEvent.

C# doesn't support anonymous interface implementations, so if your interface has multiple methods then you'll have to define a concrete class somewhere. Depending on the usage you could just have this class contain delegate properties which you can supply on creation e.g.

public class Delegates
{
    public Action Event { get; set; }
    public Func<string> GetValue { get; set; }
}

You can then create it like:

var anon = new Delegates
{
    Event = () => { ... },
    GetValue = () => "Value"
}
Lee
  • 142,018
  • 20
  • 234
  • 287
  • I think the point was in java you can instantiate an interface. – ta.speot.is Mar 23 '13 at 00:09
  • @ta.speot.is that's covered instantiating a delegate instead. – Luiggi Mendoza Mar 23 '13 at 00:11
  • @ta.speot.is - Well in Java, the interface is really just used to define the callback method. In C# these are done using delegate types, and events are build on top of those. – Lee Mar 23 '13 at 00:11
  • 2
    This breaks down if the interface is more elaborate. – ta.speot.is Mar 23 '13 at 00:13
  • @ta.speot.is - What do you mean by 'more elaborate'? If the event has associated data then you can use a different delegate type. If it has multiple callback methods then it represents multiple events. – Lee Mar 23 '13 at 00:21
  • He is creating an anonymous class (what I called "instantiating an interface") in `simulateEvent`, what happens if you need to construct an interface with two methods and three properties on the fly? That has nothing to do with events. – ta.speot.is Mar 23 '13 at 00:36