Как создать универсальную функцию в словаре

#c# #.net #generics

#c# #.net #универсальные

Вопрос:

Возможно ли сделать

 public class MyClass : Dictionary<string, Func<string>>
  

как

 public class MyClass : Dictionary<string, Func<T>>
  

На самом деле у меня есть

 public class MyClass : Dictionary<string, Func<string>>
{
    public void MyFunction(string key)
    {
        if (this.ContainsKey(key))
            this[key]();
        else
            this["no match"]();
    }
}
  

Я хочу сделать значение универсальным. возможно ли это?

Спасибо.

Ответ №1:

Тип должен быть где-то указан, поэтому вам также придется сделать свой класс универсальным:

 public class Myclass<T> : Dictionary<string, Func<T>> {

  public T MyFunction(string key) {
    if (this.ContainsKey(key)) {
      return this[key]();
    } else {
      return this["no match"]();
    }
  }

}
  

Ответ №2:

Вы можете указать тип в качестве параметра при создании экземпляра объекта. Я предоставил рабочий код.

 using System;
using System.Collections.Generic;

namespace GenericDictionary
{
    class Program
    {

        static void Main(string[] args)
        {
            DictionaryUser dictionaryUser = new DictionaryUser();
            Console.ReadLine();
        }

        class GenericFuncDictionary<T> : Dictionary<string, Func<T>>
        {
            public void DisplayValues()
            {
                foreach(Func<T> fun in this.Values)
                    Console.WriteLine(fun());
            }
        }

        class DictionaryUser
        {
            public DictionaryUser()
            {
                GenericFuncDictionary<string> myDictionary = new GenericFuncDictionary<string>();
                myDictionary.Add("World", FunWorld);
                myDictionary.Add("Universe", FunUniverse);
                myDictionary.DisplayValues();
            }
            public string FunWorld()
            {
                return "Hello World";
            }
            public string FunUniverse()
            {
                return "Hello Universe";
            }
        }
    }
}
  

Ответ №3:

Было не совсем ясно, хотите ли вы, чтобы ваш параметр type Func<T> был частью MyClass подписи (например MyType<T> ), как предполагалось в других ответах, или если вы хотели иметь возможность хранить любой тип Func<T> в словаре и вычислять правильные вещи во время выполнения.

Если вам нужен последний вариант и вы используете C # 4.0, то вы можете сделать это:

 class MyClass : Dictionary<string, Func<object>>
{
    public void MyFunction<T>(string key)
    {
        Func<object> func;
        if (this.TryGetValue(key, out func) amp;amp; func is Func<T>)
            func();
        else
        {
            func = this["no match"];
            if (func is Func<T>)
                func();
            else
            { */ do something else, or maybe you don't care about the type of "no match" */ }
        }
    }
}
  

Причина использования C # 4.0 с этим заключается в том, что теперь вы можете писать:

 MyClass myClass = ...;
Func<string> stringFunc = ...;
myClass["test"] = stringFunc;
  

До C # 4.0 не было возможности привести Func<string> к Func<object> . В этом случае вам пришлось бы написать любую из этих двух строк (не потрудитесь проверить, скомпилировалась ли первая строка до версии 4.0):

 myClass["test"] = () => stringFunc();
myClass["test"] = () => (object) stringFunc();
  

И чтобы использовать ее, вы могли бы написать:

 MyClass myClass = ...;
myClass.MyFunction<string>("test");
  

Ответ №4:

Следующий сценарий позволил бы вам использовать словарь элементов для отправки в качестве входных параметров и получить то же самое, что и выходные параметры.

Сначала добавьте следующую строку вверху:

 using TFunc = System.Func<System.Collections.Generic.IDictionary<string, object>, System.Collections.Generic.IDictionary<string, object>>;
  

Затем внутри вашего класса определите словарь следующим образом:

      private Dictionary<String, TFunc> actions = new Dictionary<String, TFunc>(){

                        {"getmultipledata", (input) => 
                            {
                                //DO WORKING HERE
                                return null;
                            } 
                         }, 
                         {"runproc", (input) => 
                            {
                                //DO WORKING HERE
                                return null;
                            } 
                         }
 };
  

Это позволило бы вам запускать эти анонимные функции с синтаксисом, подобным этому:

 var output = actions["runproc"](inputparam);