read return value from delegate
Asked Answered
E

5

8

I am not sure if I understood the usage of delegates correctly but I would like to read delegate return value in publisher class. The example is below with description.

//Publisher class
    public class ValidateAbuse
    {

    public delegate List<String> GetAbuseList();
    public static GetAbuseList Callback;

    public void Ip(string ip)
    {
    //   I would like to read GetAbuseList value (List<String>) here. How to do that?
    }

    }


//Subscriber class
    class Server
    {

        public static void Start()
        {
            ValidateAbuse.Callback = GetIpAbuseList;
            ValidateAbuse.Ip(MyIp);
        }

        private static List<string> GetIpAbuseList()
        {
            //return List<String> to ValidateAbuse class and use return value in public void Ip(string ip) method 
        }
Extremist answered 16/4, 2012 at 12:22 Comment(4)
I suggest you don't use static but instead pass the callback as a parameter when creating the ValidateAbuse instance. Also, you can use the built-in delegate Func<List<string> instead of creating your own.Toulouse
@TorbjörnKalin Could you please post a example? I am new to c# and example would be more clearly for me.Extremist
You're invoking ValidateAbuse.Ip statically (without an instance), however the Ip method is not actually defined static.Borstal
@Extremist too much to write in a comment, so I posted an answer.Toulouse
R
6
public void Ip(string ip)
{
  if (Callback != null)
  {
    List<String> valueReturnedByCallback = Callback();
  }
}
Romany answered 16/4, 2012 at 12:27 Comment(0)
I
2

Here's a version that does not use static for ValidateAbuse and that uses the built-in Func<T> delegate.

public class ValidateAbuse
{
    private Func<List<string>> callback;

    public ValidateAbuse(Func<List<string>> callback)
    {
        this.callback = callback;
    }

    public void Ip(string ip)
    {
        var result = callback();
    }
}

public class Server
{
    public static void Start()
    {
        var validateAbuse = new ValidateAbuse(GetIpAbuseList);
        validateAbuse.Ip(MyIp);
    }

    private static List<string> GetIpAbuseList()
    {
        //return List<string> to ValidateAbuse class and use return value in public void Ip(string ip) method 
    }
}

I recommend you avoid static since that gives you a global state, which could later give you coupling problems and also makes it hard for you to unit test.

The other answers given so far has a guard clause, checking Callback for null. Unless that is expected behaviour (that Callback is null) I would avoid this. It's better to crash early than to get hard to debug errors later on.

I would also try to make the Server non-static.

Invert answered 16/4, 2012 at 14:32 Comment(0)
B
0

It should be as simple as:

// Ip in your code sample is missing static
public static void Ip(string ip)
{
    List<string> abuseList;
    if (Callback != null)
        abuseList = Callback()
}

However you can avoid creating a delegate all together by using a Func:

public static Func<List<string>> Callback;
Borstal answered 16/4, 2012 at 12:28 Comment(0)
J
0

Try this: Read more from here http://msdn.microsoft.com/en-us/library/bb534960%28v=vs.110%29.aspx

internal delegate int PowerOfTwo();
void Main(){
    PowerOfTwo ch = new PowerOfTwo(CheckPower);
    Console.WriteLine(ch());
    }
int CheckPower(){
    return 2*2;
    }
Jacqui answered 19/11, 2014 at 10:9 Comment(0)
A
0

@Torbjörn Kalin's answer is good, but only if you have only 1 delegate you want to get the return value from. If you want to retrieve the return values of more than one delegate, this is how you do it:

//Publisher class
public class ValidateAbuse
{        
    public delegate List<String> GetAbuseList();
    public static GetAbuseList Callback;

    public void Ip(string ip)
    {        
        foreach (GetAbuseList gal in Callback.GetInvocationList())
        {                
            List<string> result = gal.Invoke(/*any arguments to the parameters go here*/);
            //Do any processing on the result here
        }
    }            
}


//Subscriber class
class Server
{

        public static void Start()
        {
            //Use += to add to the delegate list
            ValidateAbuse.Callback += GetIpAbuseList;
            ValidateAbuse.Ip(MyIp);
        }

        private static List<string> GetIpAbuseList()
        {
            //return code goes here
            return new List<String>();
}

This will invoke each delegate one after the other, and you can process the output of each delegate separately from each other.

The key here is using the += operator (not the = operator) and looping through the list that is retrieved by calling GetInvocationList() and then calling Invoke() on each delegate retrieved.

I figured this out after reading this page: https://www.safaribooksonline.com/library/view/c-cookbook/0596003390/ch07s02.html (altho it was partially because I already had an idea what to do, and I didn't start a free trial to read the rest)

Hope this helps!

Arrogate answered 17/1, 2018 at 4:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.