Reputation: 18127
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
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
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
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
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
Reputation: 4622
public void Ip(string ip)
{
if (Callback != null)
{
List<String> valueReturnedByCallback = Callback();
}
}
Upvotes: 6