4

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);
                }
            }
    }       
}
2

2 Answers 2

5

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
    }


}
Sign up to request clarification or add additional context in comments.

Comments

3

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.

5 Comments

I adopted the solution given by @AndreySarafanov but I am sure the information you have shared will be of much use as I go forward in this project. Thanks a lot
Hi. After a bit of struggle I found your 3rd method best suited for my use case. But when I am using App.Current.Resources["ResourceName"] it gives ` Invalid cross-thread access.` error. I am actually calling it from AsyncCallback function. public void UserAvailabilityCallback(IAsyncResult ar). This runs on separate thread I as I know. Can you suggest a fix please. And please correct me if I am doing wrong somewhere. I am using Deployment.Current.Dispatcher to fix this. Can something else be done instead of this?
@PratPor It is another question that does not directly relates to this one, so you should probably ask it as a completely new question - this one has already served its goal. Just read stackoverflow.com/questions/8240490/… before asking to get better understanding of possible issues and solutions.
I think the first option is a more useful approach since it will handle the case of more than one interface method better and also allow you to maintain your interfaces from Java to C# (delegates cannot be substituted for interfaces generally).
@DaveDoknjas Yes, delegates could be somewhat derisively called a poor man's Observer Pattern. They are an effective solution for UI-event handling(inside one UI element), but for anything more intricate you end up using more complex solutions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.