I'm trying to create an event delegate where the parameter is strongly typed to match the current class, like this:
public class HPCRequest
{
public delegate void RequestCompleteHandler(HPCRequest request);
public event RequestCompleteHandler RequestComplete;
The problem is that the point of this class is to be inherited, and what I really want is for all those inheriting classes to have the "RequestComplete" event, where the delegate is typed for that class:
public class HPCGetConfig : HPCRequest
{
//I want this class to effectively inherit something like this:
//public delegate void RequestCompleteHandler(HPCGetConfig request);
This is because currently, when I have a function that handles one of my "RequestComplete" events, I currently have to do this:
myGetConfigRequest.RequestComplete += new HPCRequest.RequestCompleteHandler(HPCGetExpectedLosses_RequestComplete);
void HPCGetConfig_RequestComplete(HPCRequest request)
{
HPCGetConfig thisRequest = request as HPCGetConfig;
//This should be strongly typed in the first place.
But I want to be able to do something like this:
request.RequestComplete += new HPCGetConfig.RequestCompleteHandler(HPCGetConfig_RequestComplete);
request.SendRequestAsync();
}
void HPCGetConfig_RequestComplete(HPCGetConfig request)
{
request.RequestComplete -= HPCGetConfig_RequestComplete;
Attempts
I've tried this:
public delegate void RequestCompleteHandler<T>(T request) where T : HPCRequest;
public event RequestCompleteHandler<T> RequestComplete;
but when I try to invoke the event from within the base class using RequestComplete(this);
, I get a compile time error: `Delegate 'RequestCompleteHandler' has some invalid arguments.
This happens whether or not I set up the entire HPCRequest
class as HPCRequest<T>
by going:
public class HPCRequest<T> where T : HPCRequest<T>
{
public delegate void RequestCompleteHandler<T>(T request);
public event RequestCompleteHandler<T> RequestComplete;
public class HPCGetConfig : HPCRequest<HPCGetConfig> { ...
The same error occurs when I try to invoke the event: RequestComplete(this);
I've also tried all forms of creating the delegate and event and overriding them, such as in doing:
public class HPCRequest
{
public delegate void RequestCompleteHandler(HPCRequest request);
public virtual event RequestCompleteHandler RequestComplete;
public sealed class HPCGetConfig : HPCRequest
{
public delegate void RequestCompleteHandler(HPCGetConfig request);
public override event RequestCompleteHandler RequestComplete;
But this gives me a compile time error because I cannot override the RequestComplete event with one of a different delegate type.
Any other ideas?
Edit
Templating the entire HPCRequest class is not an option, after a very thorough attempt, I see that it just screws up every attempt to use the type HPCRequest as a placeholder for any request type. If this solution is going to work, the class HPCRequest
must be able to be instantiated and inherited from without specifying a type parameter. I'll need a solution that doesn't require templating HPCRequest
.
To make sure everyone know exactly how I'm trying to use this, I pasted some sample code into pastebin that should let you experiment with ways of getting this event templating working without breaking anything. Here it is: http://pastebin.com/bbEYgLj1
What you could try:
public abstract class HPCRequest<T> where T : HPCRequest<T>
{
public delegate void RequestCompleteHandler(T request);
public event RequestCompleteHandler RequestComplete;
protected void RaiseRequestComplete(T request)
{
if (RequestComplete != null)
{
RequestComplete(request);
}
}
}
public class Foo : HPCRequest<Foo>
{
public void Bar()
{
RaiseRequestComplete(this);
}
}
public class Example
{
public static void Test()
{
var request = new Foo();
request.RequestComplete += RequestComplete;
}
static void RequestComplete(Foo request)
{
// It's a Foo!
}
}
This self-referential generic constraint allows what you want I think. I added the protected RaiseRequestCompleted
so you can still raise the event from classes that inherit from HCPRequest. Otherwise, only HCPRequest
would be allowed to do so.
UPDATE: I updated the code to pass this
and added sample code that matches your desired result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With