Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to reimplement Java listeners with anonymous classes in C#

I am trying to replicate my Java code in C# and I wish to know how can I replicate this Java functionality in C#.

Util.java

public class Util
{
    public void function(String s, final SetAvailabilityStatusListener setStatusListener)
    {
        // ....
    }

    public static interface SetAvailabilityStatusListener {
        public void setAvailabilityStatus(Status status);
    }
}

Activity.java

public class Activity
{
    public void anotherFunction()
    {
        util.function("name", new SetAvailabilityStatus()
            {
                @Override
                public void setAvailabilityStatus(Status status) {
                    loginSetAvailabilityStatus(status);
                }
            }
    }       
}
like image 406
pratpor Avatar asked Feb 12 '23 09:02

pratpor


2 Answers

Use delegates. They are used in C# instead of Java anonymous classes that implement interfaces.

public class Util
{
    public void Function(String s, Action<Status> setStatusListener)
    {
        // ....
        setStatusListener("myStatus");
    }
}

public class Activity
{
    private Util util = new Util();
    public void AnotherFunction()
    {
        util.Function("name", status => LoginSetAvailabilityStatus(status));
    }

    public void LoginSetAvailabilityStatus(string status){
        //do something with status
    }


}
like image 94
AndreySarafanov Avatar answered Feb 15 '23 11:02

AndreySarafanov


I was unable to find suitable duplicate, so:

1. C# does not have anonymous classes like Java does, but no one stops you from creating needed listener classes manually

public class Util
{
    public void Function(String s, ISetAvailabilityStatusListener setStatusListener)
    {
        // ....
    }

    public interface ISetAvailabilityStatusListener {
        public void SetAvailabilityStatus(Status status);
    }
}

public class Activity
{
    private class MySetAvailabilityStatusListener: Util.ISetAvailabilityStatusListener
    {
        public void SetAvailabilityStatus(Status status) 
        {
            // do your handling, but nested classes have some differences with anonymous Java classes, so it may require additional infrastructure.
        }
    }

    public void AnotherFunction()
    {
        utilObj.Function("name", 
            new MySetAvailabilityStatusListener())
    }       
}

It is so-called observer design pattern (just without unregistration method!!).

2. As it has been already suggested by @AndreySarafanov you can use Action Delegates and lambda expressions:

public class Util
{
    public void Function(String s, Action<Status> statusChangeListener)
    {
        // ....
    }
}

public class Activity
{
    public void AnotherFunction()
    {
        utilObj.Function("name", 
            (status) => 
            {
                loginSetAvailabilityStatus(status);
            }
    }       
}

3. C# has another more simple mechanism to deal with event-handling(subsrciption) mechanics - events and delegates

public class StatusEventArgs : EventArgs
{
    //...
}

public class Util
{
    public void SomeFunction()
    {
        // ....
        if (this.OnAvailabilityChanged != null)
            OnAvailabilityChanged(this, new StatusEventArgs(status));
    }

    public event EventHandler<StatusEventArgs> OnAvailabilityChanged
}

public class Activity
{
    public void AvailabilityStatusChangedHandler(object sender, EventArgs<Status> eventArgs) 
    {
    }

    public void AnotherFunction()
    {
        utilObj.OnAvailabilityChanged += this.AvailabilityStatusChangedHandler;
    }       
}

It does not allow you to associate the name property with event handler, well, you can overcome it with special registration method, but it will reduce the usability of events, so you should probably stick with another solution.

like image 29
Eugene Podskal Avatar answered Feb 15 '23 11:02

Eugene Podskal