【问题标题】:Anonymous method shortest syntax匿名方法最短语法
【发布时间】:2014-10-28 10:10:31
【问题描述】:

关于匿名方法,给定一个第一个参数为 Func 的方法“WriteConditional”,有没有办法甚至消除额外的“() =>”语法?

看起来你应该能够做到,因为它是明确的,只要没有额外的重载可以接受字符串,对吧?

void Program()
{
  IDictionary<string,string> strings = new Dictionary<string,string>() { {"test","1"},{"test2","2"}};

  //seems like this 'should' work, because WriteConditional has no other overload
  //that could potentially make this ambiguous
  WriteConditional(strings["test"],"<h3>{0}</h3>");

  //since WriteConditional_2 has two overloads, one that has Func<string> and another with string,
  //the call could be ambiguous, so IMO you'd definitely have to "declare anonymous" here:
  WriteConditional_2(()=>strings["test"],"<h3>{0}</h3>");      
}

void WriteConditional(Func<string> retriever, string format)
{
   string value = retriever.Invoke();
   if(string.IsNullOrEmpty(value)==false)
      Console.WriteLine(string.Format(format,value));
}

void WriteConditional_2(Func<string> retriever, string format)
{
   string value = retriever.Invoke();
   if(string.IsNullOrEmpty(value)==false)
      Console.WriteLine(string.Format(format,value));
}

void WriteConditional_2(string value, string format)
{
   if(string.IsNullOrEmpty(value)==false)
      Console.WriteLine(string.Format(format,value));
}

【问题讨论】:

  • is there a way to even eliminate the extra "() =&gt; " syntax? 为什么(如果我没看错你的问题)?该语法专门表示匿名方法。读过的人,都懂。消除它意味着我不知道我会调用哪个方法签名,或者它试图做什么。
  • 嗯,这个语法特指“lambda 表达式”。 delegate { return strings["test"]; } 将是一个匿名方法。
  • 您能否评论一下“......像这样'应该'如何工作,” - 将string 转换为函数的预期行为是什么?
  • 当然,任何带有任何参数的 lambda 显然都不会在这里考虑,因为您没有参数名称可以使用它。这消除了 lambda 的绝大多数实际用途。
  • 这将要求编译器在知道它正在解析的内容之前进行大量的预测。这也意味着您无法仅通过语法来判断 foo(a) 是立即评估还是延迟评估。

标签: c# func anonymous-methods


【解决方案1】:

,没有这种方法。但是,您可以作弊并提供自己的重载:

void WriteConditional(Func<string> retriever, string format)
{
   var value = retriever();
   if(string.IsNullOrEmpty(value)==false)
      Console.WriteLine(string.Format(format,value));
}

void WriteConditional(string value, string format)
{
   WriteConditional(() => value, format);
}

【讨论】:

  • 这在语义上是不同的。它会立即将表达式计算为其值,而不是关闭变量并推迟执行,直到调用委托为止。
  • @Servy 正确。正如我所说,这是作弊,它并不完全相同。这就是为什么我的回答是“不”:)
  • 有点令人失望,但可以理解......因为如果为 WriteConditional 创建了一个将字符串作为第一个参数的新重载,那么操作就会发生语义变化。似乎编译器应该能够轻松地将一个将字符串返回到 Func 实例中的方法强制执行。
  • @enorl76 这会产生一些惊人的错误,因为这意味着您可能会传递一个表达式,而没有意识到它的执行被推迟了。不再能够仅通过查看来判断表达式是否立即被评估。
  • @RaymondChen 我可以同意你的第一句话,但是大多数 LINQ 方法经常对语句运行的确切时间含糊不清,我看不出这有什么不同......
【解决方案2】:
is there a way to even eliminate the extra "() => " syntax?

我也认为答案是否定的,但如果您的 func 通过使用运算符重载返回自定义类,您可以做一些事情。
如果您可以将操作重载与扩展方法一起使用,这对于其他类型也是可能的

using System;

public class MyClass
{
   public static implicit operator Func<MyClass>(MyClass obj)
   {
     return () => { Console.WriteLine("this is another cheat"); return new MyClass(); };
   }
}


public class Program
{
   static void Main(string[] args)
   {

      MyClass x = new MyClass();
      WriteConditional(x);
      Console.ReadLine();
   }

   static void WriteConditional(Func<MyClass> retriever) {  }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 2011-08-16
    • 1970-01-01
    相关资源
    最近更新 更多