【问题标题】:SortedList with string as index and function pointer or delegate as value? And Calling Functions by strings?以字符串作为索引和函数指针或委托作为值的 SortedList?并通过字符串调用函数?
【发布时间】:2011-08-24 20:19:28
【问题描述】:

我不熟悉委托和 lambda,但此时我必须做这两件事:

  • 其中之一是:

我需要将函数传递给 SortedList。不知道怎么弄。

为什么我需要它,是:

private string Func1(string s) { return s + "1"; }
private string Func2(string s) { return s + "2"; }
private string Func3(string s) { return s + "3"; }

private void WhatEver()
{
SortedList<string, ???> list = new SortedList<string, ???>;
list.Add("Func1", Func1);
list.Add("Func2", Func2);
list.Add("Func3", Func3);

// And after that I have to pass values and get results from functions
// Like

Console.WriteLine(list["Func1"]("Test"));
Console.WriteLine(list["Func2"]("Test"));
Console.WriteLine(list["Func3"]("Test"));

// Output should be:
//
// Test1
// Test2
// Test3

}
  • 第二:

可以用字符串调用函数吗?

例如:

假设我有三个文本框和一个函数:

tbFunction
tbArgument
tbResult

private string Test(string number)
{
    int x = int.Parse(number);
    return (x * x).ToString();
}

假设我在 tbFunction.Text 中有“Test”,在 tbArgument.Text 中有“2”,我怎样才能将结果带到 tbResult.Text

【问题讨论】:

  • 我真的不知道你在这个问题的第一部分想要做什么。请删除有关将函数传递给 SortedList 的特定于实现的详细信息,然后说出您要完成的工作,好吗? -- 另外,看起来你正在尝试做类似字典,而不是 SortedList...

标签: c# function delegates lambda


【解决方案1】:

花了一段时间才弄清楚你想要什么。所以,如果我正确地跟随你,你想要:

  • 给定字符串变量中的方法名称,调用比方法。

简单的答案是没有内在的方法可以做到这一点。您可能可以使用反射来拼凑一些东西,但这会付出更多的努力而不值得。

所以,我们需要创建自己的调度表:

// class member
var jumptbl = new SortedList<string, Func<string, string> >();

 // :  (in ctor)
jumptbl.Add("Test", Test);

// :  (I'm guessing this is in a Click handler)
tbResult.Text = jumptbl[tbFunction.Text](tbArgument.Text)

更进一步,用于调用它的名称(在字符串中)不需要与函数本身的名称有任何联系。该方法甚至不必有名称:

jumptbl.Add("Func1", s=> s + "1");
jumptbl.Add("Func2", s=> s + "2");
jumptbl.Add("Func3", s=> s + "3");

【讨论】:

  • 我应该在列表的第二个参数中声明什么作为值类型?
  • @haxxoromer: "Func" 这是一个接受字符串并返回字符串的委托。
【解决方案2】:

这实际上是一个反射的工作,与 lambdas 或 delegates 无关。

你需要做一些类似...

MethodInfo method = typeof(ClassWithMethods).GetMethod(tbFunction.Text);
ClassWithMethods obj = new ClassWithMethods();
string result = method.Invoke(obj, new[] {tbArgument.Text});
tbResult.Text = result;

查看 System.Reflection 文档。

【讨论】:

    【解决方案3】:
    public delegate string YourDelegate(string number);
    SortedList<string, YourDelegate> methods = new SortedList<string, YourDelegate>();
    
    // Add more methods here
    methods .Add("Test", Test);
    ...
    
    public string CallMethod(string methodName, string number)
    {
        YourDelegate method;
        if (methods.TryGetValue(methodName, out method))
            return method(number);
        else
            return "Unknown method";
    }
    ...
    
    public void button1_Click(object sender, EventArgs e)
    {
        tbResult.Text = CallMethod(tbFunction.Text, tbArgument.Text);
    }
    

    我认为这正是您所要求的。 我个人会使用字典,但这可能只是个人喜好问题。

    您也可以使用反射,这样您就不需要在列表中注册每个方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-05
      • 2018-03-14
      • 2013-01-04
      相关资源
      最近更新 更多