Embedd_0913
Embedd_0913

Reputation: 16555

Problem when with generic delegates in C#

I have a sample program where I have a class called ObserverTest where I have two methods

one for subscription and one for notify for any type T but I get some build errors.

Following is my sample code>

using System;

namespace ConsoleApplication1
{
   class Program
   {
      static void Main(string[] args)
      {
         ObserverTest obs = ObserverTest.Instance();
         obs.SubscribeToChange<int>(GotChange);
         obs.NotifyChange<int>(200);
         Console.ReadLine();
      }

      private static void GotChange(int val)
      {
         Console.WriteLine(string.Format("Changed value is {0}", val));
      }
   }

   public class ObserverTest
   {
      private static ObserverTest _obsTest;
      private Action<T> _observer;

      private ObserverTest()
      {
      }

      public static ObserverTest Instance()
      {
         return _obsTest = _obsTest == null ? new ObserverTest() : _obsTest;
      }

      public void NotifyChange<T>(T val)
      {
         _observer(val);
      }

      public void SubscribeToChange<T>(Action<T> observer)
      {
         _observer = observer;
      }

   }
}

and followings are the errors:

Error   1   The type or namespace name 'T' could not be found (are you missing a using directive or an assembly reference?) C:\Users\Administrator\AppData\Local\Temporary Projects\ConsoleApplication1\Program.cs  24  22  ConsoleApplication1

Error   2   The field 'ConsoleApplication1.ObserverTest._observer' cannot be used with type arguments   C:\Users\Administrator\AppData\Local\Temporary Projects\ConsoleApplication1\Program.cs  37  10  ConsoleApplication1

Can anyone please help me in removing the errors ?

Thanks in advance.

Upvotes: 1

Views: 323

Answers (3)

VMAtm
VMAtm

Reputation: 28355

Try to add generic in the class definition:

public class ObserverTest<T>

complete code:

using System;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ObserverTest<int> obs = ObserverTest<int>.Instance();
            obs.SubscribeToChange<int>(GotChange);
            obs.NotifyChange<int>(200);
            Console.ReadLine();
        }

        private static void GotChange(int val)
        {
            Console.WriteLine(string.Format("Changed value is {0}", val));
        }
    }

    public class ObserverTest<T>
    {
        private static ObserverTest<T> _obsTest;
        private Action<T> _observer;

        private ObserverTest()
        {
        }

        public static ObserverTest<T> Instance()
        {
            return _obsTest = _obsTest == null ? new ObserverTest<T>() : _obsTest;
        }

        public void NotifyChange<E>(T val)
        {
            _observer(val);
        }

        public void SubscribeToChange<E>(Action<T> observer)
        {
            _observer = observer;
        }

    }
}

Upvotes: 4

myermian
myermian

Reputation: 32515

The problem you are having is that you are declaring a field member that has a generic type and the class does not:

public class ObserverTest
{
     private static ObserverTest _obsTest;
     private Action<T> _observer;

     ...
}

So when you try to create an instance of the ObserverTest class, it tries to setup the field members and runs into the problem of not knowing what concrete type _observer is.


To fix this you'll have to define the class with a generic parameter and any calls that instantiate the class:

public class ObserverTest<T>
{
     private static ObserverTest _obsTest;
     private Action<T> _observer;

     public static ObserverTest<T> Instance<T>()
     {
         ...
     }

     ...
}

Upvotes: 0

FishBasketGordo
FishBasketGordo

Reputation: 23142

If you have a member that's a generic, like _observer, you need to put a type argument on the ObserverTest class, like so:

public class ObserverTest<T> {
}

Of course, you'll need to modify your Instance method as well.

Upvotes: 2

Related Questions