【问题标题】:How to return value with anonymous method?如何使用匿名方法返回值?
【发布时间】:2012-05-18 06:02:37
【问题描述】:

失败了

string temp = () => {return "test";};

有错误

无法将 lambda 表达式转换为类型“字符串”,因为它不是委托类型

错误是什么意思,我该如何解决?

【问题讨论】:

  • 为什么这个问题是谷歌搜索错误“匿名函数转换为无效返回委托不能返回值”时的第一个结果,而它显然与它无关?

标签: c# .net lambda


【解决方案1】:

这里的问题是您定义了一个匿名方法,它返回一个string,但试图将它直接分配给string。这是一个表达式,当被调用时会产生一个string,它不是直接的string。它需要分配给兼容的委托类型。在这种情况下,最简单的选择是Func<string>

Func<string> temp = () => {return "test";};

这可以在一行中通过一点转换或使用委托构造函数来确定 lambda 的类型,然后进行调用。

string temp = ((Func<string>)(() => { return "test"; }))();
string temp = new Func<string>(() => { return "test"; })();

注意:两个样本都可以缩写为缺少{ return ... }的表达式形式

Func<string> temp = () => "test";
string temp = ((Func<string>)(() => "test"))();
string temp = new Func<string>(() => "test")();

【讨论】:

  • 谢谢。所以没有办法在一行上做所有事情(包括分配字符串)?我想要的值(“test”,实际上是现实生活中的一个变量)在另一个 lambda 中,所以如果我尝试像上面那样定义,我会失去范围。
  • @4thSpace 它可以通过一些邪恶的铸造在一行中完成。我更新了我的答案以显示方式
  • 或者在这种情况下,只是Func&lt;string&gt; temp = () =&gt; "test";
  • 或者在您编辑的情况下,string temp = new Func&lt;string&gt;(() =&gt; "test")();
  • 完美!如果我想传入一个 int,你能在一行中显示吗?我试过了,但不行: ((Func)((4) => {return "test";}))();
【解决方案2】:

您正在尝试将 函数委托 分配给字符串类型。试试这个:

Func<string> temp = () => {return "test";};

你现在可以这样执行函数了:

string s = temp();

“s”变量现在将具有值“test”。

【讨论】:

    【解决方案3】:

    使用一点辅助函数和泛型,您可以让编译器推断类型,并缩短一点:

    public static TOut FuncInvoke<TOut>(Func<TOut> func)
    {
        return func();
    }
    
    var temp = FuncInvoke(()=>"test");
    

    旁注:这也很好,因为您可以返回匿名类型:

    var temp = FuncInvoke(()=>new {foo=1,bar=2});
    

    【讨论】:

    • 有趣的技术。这会增加运行时开销,还是全部在编译时?
    • @ToolmakerSteve:我的猜测是它会增加一点运行时开销(它将对匿名方法的调用包装在另一个方法中) - 但是,我怀疑它还取决于 FuncInvoke 的位置方法已定义(与调用它的程序集相同的程序集与不同的程序集等),因为它可能是编译器可以“内联”的那种东西。人们通过编写快速测试程序、编译然后分解生成的 IL 来回答这类问题。
    • @ToolmakerSteve 继最后一次对性能影响的“猜测”之后,我想补充一点,即使这对性能产生的最坏情况影响也几乎为零(一个额外的函数调用,一个非-虚拟,静态方法)。任何使用这种技术的人都可能这样做,因为他们正在抛出 lambdas。这意味着他们可能在某个地方至少使用了几个 LINQ 扩展方法,所以他们无意中将几个 LINQ 方法链接在一起的可能性是相当大的,这种方式对性能的伤害比一个额外的函数调用差 100,000 倍;)
    【解决方案4】:

    您可以使用带参数的匿名方法:

    int arg = 5;
    
    string temp = ((Func<int, string>)((a) => { return a == 5 ? "correct" : "not correct"; }))(arg);
    

    【讨论】:

    • 你可以,但请解释这是对问题的回答。
    【解决方案5】:

    匿名方法可以使用 func 委托返回值。 这是一个示例,我展示了如何使用匿名方法返回值。

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApp1
    {
        class Program
        {
    
    
            static void Main(string[] args)
            {
                Func<int, int> del = delegate (int x)
                  {
                      return x * x;
    
                  };
    
                int p= del(4);
                Console.WriteLine(p);
                Console.ReadLine();
            }
        }
    }
    

    【讨论】:

      【解决方案6】:

      这是另一个使用 C# 8 的示例(也可以与支持并行任务的其他 .NET 版本一起使用

      using System;
      using System.Threading.Tasks;
      
      namespace Exercise_1_Creating_and_Sharing_Tasks
      {
          internal static class Program
          {
              private static int TextLength(object o)
              {
                  Console.WriteLine($"Task with id {Task.CurrentId} processing object {o}");
                  return o.ToString().Length;
              }
      
              private static void Main()
              {
                  const string text1 = "Welcome";
                  const string text2 = "Hello";
      
                  var task1 = new Task<int>(() => TextLength(text1));
                  task1.Start();
      
                  var task2 = Task.Factory.StartNew(TextLength, text2);
      
                  Console.WriteLine($"Length of '{text1}' is {task1.Result}");
                  Console.WriteLine($"Length of '{text2}' is {task2.Result}");
      
                  Console.WriteLine("Main program done");
                  Console.ReadKey();
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-08
        • 1970-01-01
        • 2015-01-25
        • 2016-02-19
        • 2019-09-05
        • 2012-04-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多