#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);