0

I have two interfaces for a simple observer pattern:

// ObserverPattern.cs
public interface Observer<E>
{
    void OnFire(E e);
}

public interface Subject<E>
{
    List<Observer<E>> Observers { get; set; }

    void AddObserver(Observer<E> observer)
    {
        Observers.Add(observer);
    }

    void Fire(E e)
    {
        foreach (var t in Observers)
        {
            t.OnFire(e);
        }
    }
}

And two classes that implement this interface:

// CharacterObserver.cs
public enum Event {
    Action,
    Normal,
    Skill,
    Burst
}

public class CharacterSubject : Subject<Event>
{
    public List<Observer<Event>> Observers { get; set; } = new();
}

public class CharacterObserver : Observer<Event>
{
    public void OnFire(Event e)
    {
        switch (e)
        {
            case Event.Action:
                Console.WriteLine("Action!");
                break;
            case Event.Normal:
                break;
            case Event.Skill:
                break;
            case Event.Burst:
                break;
            default:
                throw new ArgumentOutOfRangeException(nameof(e), e, null);
        }
    }
}

However trying to call AddObserver or Fire on a CharacterSubject doesn't work:

CharacterSubject subject = new CharacterSubject();
subject.AddObserver(new CharacterObserver());
subject.Fire(Event.Action);

It only works when I reimplement AddObservers or Fire in CharacterObserver (either with the default implementations or without them). Why is it that I can't call those methods despite it satisfying the interface requirements.

Lnio Yarschov
  • 23
  • 1
  • 2

2 Answers2

0

Default method implementations for an interface (provided a concrete class doesn't implement it) can only be accessed via the interface reference. So you need to declare your variable that interface if you wish to call it.

Subject<Event> subject = new CharacterSubject();
subject.AddObserver(new CharacterObserver());
subject.Fire(Event.Action);
Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
0

This is because you are not really treating your variable subject as an interface. If you want to use the implementations given by the interface, you should change the type of subject to be Subject<Event> to get the implementations, otherwise it will look for the overridden implementations specific to the CharacterSubject class!