3

I am trying to create this simple interface. I want it somehow to be able to fire an event. This is what I have till now (doesn't compile, just my thoughts)

public interface IAsyncSearch<TTermType, TResultsEventType>
                                                 where TResultsEventType:delegate
{
    event TResultsEventType SearchCompletedEvent;
    void SearchAsync(TTermType term);
}

Is something similar even possible? I know that a type is expected in the where statement.

Odys
  • 8,951
  • 10
  • 69
  • 111

3 Answers3

2

Try this

public interface IAsyncSearch<TData, TArgs>
{
    event EventHandler<SpecialDataEventArgs<TArgs>> SearchCompletedEvent;
    void SearchAsync(TData term);
}

public class SpecialDataEventArgs<T> : EventArgs
{
    public SpecialDataEventArgs(T data)
    {
        Data = data;
    }

    public T Data { get; private set; }
}
Lonli-Lokli
  • 3,357
  • 1
  • 24
  • 40
2

All event types ought to derive from EventHandler<>, the standard .NET event handler type. Helps anybody that reads your code recognize it quickly. And even more appropriate here, it readily solves your problem:

    public interface IAsyncSearch<TTermType, TResultsArgType> 
        where TResultArgType : EventArgs 
    {
        event EventHandler<TResultsArgType> SearchCompletedEvent;
        void SearchAsync(TTermType term);
    }
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
1

Events work only with delegate types. And there is no way to constrain type parameter to be a delegate in C#. Because of that, I don't think what you want is possible in C#.

According to Jon Skeet, it actually may be possible to do this in CIL, so maybe if you wrote that type in CIL, you could be able to use it from C# the way you want.

EDIT: You can create such type in CIL, but it seems you can't use it property from C#. It seems you can't implement it. And calling the event methods using += doesn't work either. But calling them using the add_SearchCompletedEvent does work.

svick
  • 236,525
  • 50
  • 385
  • 514