Tomas
Tomas

Reputation: 18127

read return value from delegate

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 
        }

Upvotes: 8

Views: 23145

Answers (5)

shieldgenerator7
shieldgenerator7

Reputation: 1756

@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!

Upvotes: 0

Elshan
Elshan

Reputation: 7693

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

Upvotes: 0

Torbj&#246;rn Kalin
Torbj&#246;rn Kalin

Reputation: 1986

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.

Upvotes: 2

M.Babcock
M.Babcock

Reputation: 18965

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;

Upvotes: 0

Hari
Hari

Reputation: 4622

public void Ip(string ip)
{
  if (Callback != null)
  {
    List<String> valueReturnedByCallback = Callback();
  }
}

Upvotes: 6

Related Questions