C# equivalent of creating anonymous class that implements an interface

后端 未结 2 1099
被撕碎了的回忆
被撕碎了的回忆 2020-12-11 17:33

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,

相关标签:
2条回答
  • 2020-12-11 17:55

    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"
    }
    
    0 讨论(0)
  • 2020-12-11 17:56

    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();
        }
    }
    
    0 讨论(0)
提交回复
热议问题