2

So here is the code:

  public interface IObserver<T> where T : StackEventData<T>
    {
        void HandleEvent(StackEventData<T> eventData);
    }

    public class Observer<T> : IObserver<T> where T : StackEventData<T>, new()
    {
        public StringBuilder Log = new StringBuilder();

        public void HandleEvent(StackEventData<T> eventData)
        {
            Log.Append(eventData);
        }
    }

public class StackOperationsLogger
    {
        private readonly Observer<T> observer = new Observer<T>();
    }

I need to initialize Observer observer in StackOperationsLogger without making StackOperationsLogger generic. Any suggestions?

3
  • I'm not sure I understand. What does Observer<T> mean to you if StackOperationsLogger isn't generic? How would you use it? Commented Mar 17, 2019 at 10:41
  • You just need to replace T with the appropriate type, which seems difficult because you need a type that is a StackEventData of the same type... what is StackEventData<T> and why is it generic? Commented Mar 17, 2019 at 10:41
  • Make sure you look at System.IObserver<T> just for reference because your version is so different. Personally I've been studying the pattern for a couple years now and it is really useful. Commented Mar 17, 2019 at 18:40

2 Answers 2

2

One huge problem is the original generic definition of the interface.

public interface IObserver<T> where T : StackEventData<T>

Since the type constraint is defined recursively you can't use it in the way you want. Essentially type T has to be something like this: StackEventData<StackEventData<StackEventData<StackEventData<T>>>> etc. I don't think that is what you are looking for.

I have a feeling that this is what you are looking for.

public interface IObserver<T> 
{
    void HandleEvent(StackEventData<T> eventData);
}

public class Observer<T> : IObserver<T>
{
    public StringBuilder Log = new StringBuilder();

    public void HandleEvent(StackEventData<T> eventData)
    {
        Log.Append(eventData);
    }
}

public class StackOperationsLogger
{
    private readonly Observer<DataObject> observer = new Observer<DataObject>();
}
Sign up to request clarification or add additional context in comments.

Comments

2

Provided that you have some class definitions like the following:

public class ConcreteType : StackEventData<ConcreteType>
{
}

public class StackEventData<T>
{
}

You could try this:

public class StackOperationsLogger
{
    private Observer<ConcreteType> observer = new Observer<ConcreteType>();
}

Apparently you have to design your class correspondingly. Above just highlighted how should be the "name" of the classes and what is expected from the ConcreteType class you will define -bad name..you have to change also this.

3 Comments

Except that Observer<int> doesn't compile, because int cannot be cast to StackEventData<T> - whatever that is. So this doesn't seem to answer the question...
But that doesn't compile either, because StackEventData<int> is not a StackEventData<StackEventData<int>>. That seems to be the actual problem in the OP's code.
@oerkelens Now fixed and tested :) Apparently I had to check it more carefully. Thanks !!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.