Using a Generic DelegateCollection

A while ago i posted a simple article on using a Dictionary of delegates as an alternative to a switch statement, if your not familiary with this idea or want to read the article go here Using a Dictionary as an alternative to a switch statement

I was having a little play with code a few days ago and made a little class that allows me to add this functionality to any class (see code below)

    public class DelegateCollection
        where key : class where inputType : class where outputType : class {
        private static Dictionary> _task = new Dictionary>();

        public void AddDelegate(key _key, Func callback) {
            if (!_task.ContainsKey(_key)) {
                _task.Add(_key, callback);
            }
        }

        public void RemoveDelegate(key _key) {
            if (_task.ContainsKey(_key)) {
                _task.Remove(_key);
            }
        }

        public object InvokeDelegate(key _key, inputType _value, object defaultValue = null) {
            if (_task.ContainsKey(_key)) {
                object retVal = _task[_key](_value);
                if (retVal == null) {
                    return defaultValue;
                }
                else {
                    return retVal;
                }
            }
            if (defaultValue != null) {
                return defaultValue;
            }
            else {
                return default(outputType);
            }

        }
    }

So this follows the examples shown in the other article that i linked to earlier but makes it a little cleaner in your code. An example of its use is below

        public class MyClass : DelegateCollection {
            public MyClass() {
                this.AddDelegate("test1", runTest1,"default value");
                this.AddDelegate("test2", runTest2, "default value");
            }

            public string Run(string task) {
                return this.InvokeDelegate(task, "Say Hello");
            }
            private static string runTest1(string input) {
                return input + " from Test 1";
            }
            private static string runTest2(string input) {
                return input + " from Test 2";
            }
        }

As you can see it makes the code a little cleaner because you are hiding the existence checks and the definition of the delegates.

The expanded version (without using the DelegateCollection) would look like this.

   public class MyClass  {

            private static Dictionary<string, Func<string, string>> process = new Dictionary<string, Func<string, string>>()
            {
                {"test1",runTest1},
                {"test2",runTest2}
            };

            public string Run(string task) {
                if (process.ContainsKey(task)) {
                    return process[task]("Say Hello");
                }
                return string.Empty;
            }
            private static string runTest1(string input) {
                return input + " from Test 1";
            }
            private static string runTest2(string input) {
                return input + " from Test 2";
            }
        }

Its not really hiding much from you when you use the DelegateCollection but it makes the code a little easier to read i think!

The delegate that is used is a Func<> delegate, using the inputType and outputType as the input and output types ( Func), this is what you specify when you inherit from the DelegateCollectionbasically equates to a dictionary defined as Dictionary>

Hope this makes sense….. it did while i was coding it … lol

1 Comment

Comments are closed.