Search code examples
c#functiongeneric-programming

delegate with generic type


I have a delegate public delegate void ObserverCallback<T>(T value, string key); which I want the value parameter to be whatever I want.

I have an ObserverCallback property in my class public ObserverCallback Callback; which obviously gives me this error error CS0305: Using the generic type 'Observer.ObserverCallback<T>' requires 1 type arguments. At this point, I do not know what type will be the parameter.

I would like to fix that error and to be able to pass a function through a contructor e.g. :

  • public Observer(ObserverCallback<???> callback)
  • private void ACallbackFunction(Player value)
  • var obs = new Observer(ACallbackFunction)

Solution

  • Your observer class has to be generic, and then you can use that parameter in the constructor:

    public class Observer<T>
    {
        public Observer(ObserverCallback<T> callback)
        {    
    
        }
    }
    

    Usage:

    var obs = new Observer<Player>(ACallbackFunction);
    

    If you need to use Observer as a non-generic, you could inherit from a non-generic base or implement a common interface. The caveat here is that the methods using the class generic argument T won't be available unless you explicitly cast it back to Observable<T>:

    public class Observer
    {
        public void SomeMethod()
        {
    
        }
    }
    
    public class Observer<T>
    {
        public Observer(ObserverCallback<T> callback)
        {
        }
    }
    
    var observerList = new List<Observer>();
    observerList.Add(new Observer<Player>(ACallbackFunction));
    observerList.ForEach(o => o.SomeMethod());
    

    or

    public interface IObserver
    {
        void SomeMethod();
    }
    
    public class Observer<T>: IObserver
    {
        public Observer(ObserverCallback<T> callback)
        {
        }
    
        public void SomeMethod()
        {
        }
    }
    
    var observerList = new List<IObserver>();
    observerList.Add(new Observer<Player>(ACallbackFunction));
    observerList.ForEach(o => o.SomeMethod());
    

    Note that this generic argument T will be available to any method in the class, so you don't have to write public void MyMethod<T>(T value) (which declares a generic argument T), you can then just write public void MyMethod(T value) because the generic argument is at the class level.