Welcome to MSDN Blogs Sign in | Join | Help

Generic delegate in C# 3.0 or .NET 3.5

As we do event-based programming or implement publish-subscribe pattern, we use the delegate feature from .NET heavily. The sample code below demonstrates simple usage of the feature.

    public delegate void DataChangedDelegate(int oldValue, int newValue);

 

    class Foo

    {

        public DataChangedDelegate OnDataChanged = null;

 

        private int _data = 0;

 

        public int Data

        {

            get { return _data; }

            set { UpdateData(value); }

        }

 

        private void UpdateData(int updatedData)

        {

            if (OnDataChanged != null)

            {

                OnDataChanged(_data, updatedData);

            }

            _data = updatedData;

        }

    }

We can then create an instance of Foo class, and hook up the event handler to its public delegate as shown below.

     class Program

    {

        static void Main(string[] args)

        {

            Foo foo = new Foo();

            foo.OnDataChanged += OnDataChanged;

            foo.Data = 2;

            Console.WriteLine();

        }

 

        static void OnDataChanged(int oldValue, int newValue)

        {

            Console.WriteLine("Data changes from " + oldValue + " to " + newValue);

        }

    }

 

C# 3.0 or .NET 3.5 has new feature that provides us a set of generic delegates with the name "Action" or "Func", the difference between them is Action does not have return type (void), while Func has return type (refer to MSDN documentation). So from example above we can remove following code:

    public delegate void DataChangedDelegate(int oldValue, int newValue);

and replace following code: 

        public DataChangedDelegate OnDataChanged = null;

with:

        public Action<int, int> OnDataChanged = null; 

If the delegate returns bool data type for example, then we can use Func function such as:

        public Func<int, int, bool> OnDataChanged = null;

 

Although this new feature allows us not to declare the delegate types (means less line of code), but we may use our judgement whether to use it or not. The reason is because sometimes we may prefer to name the delegate type to make us better understand the code. Another thing is we can't use the delegate type we created interchangeably with its counterpart generic delegates unfortunately even though they have same signature (and not with explicit conversion either). For example, the following code below will not work.

            DataChangedDelegate dataChanged;

            Action<int, int> genericFunc;

            dataChanged = genericFunc;      // compile error 

 

Published Saturday, November 15, 2008 10:37 PM by zainala

Comments

# Generic delegate in C# 3.0 or .NET 3.5 | Tmao Coders

Sunday, November 16, 2008 2:46 AM by Generic delegate in C# 3.0 or .NET 3.5 | Tmao Coders

# re: Generic delegate in C# 3.0 or .NET 3.5

> Another thing is we can't use the delegate type we created interchangeably with its counterpart generic delegates unfortunately even though they have same signature (and not with explicit conversion either).

While it is true that explicit cast will not work, there is still a way to do an explicit conversion here:

 DataChangedDelegate dataChanged;

 Action<int, int> genericFunc;

 dataChanged = new DataChangedDelegate(genericFunc);

And, of course, while speaking about this, it is also worth mentioning some slightly more specialized generic delegate types from .NET 2.0 such as Predicate<T>.

Sunday, November 16, 2008 3:00 AM by int19h

# re: Generic delegate in C# 3.0 or .NET 3.5

thanks a bunch for very useful tip, i learn new things everyday.

Monday, November 17, 2008 12:18 AM by zainala
Anonymous comments are disabled
 
Page view tracker