传递给这个lambda表达式的值是多少?

时间:2018-03-02 10:29:14

标签: c# lambda

请原谅我这是一个愚蠢的问题,但我不知道该去哪看。我有这个编译好的代码:

static int Main(string[] args)
{
    var parserResult = CommandLine.Parser.Default.ParseArguments<Options>(args);

    parserResult.WithParsed<Options>(options => OnSuccessfulParse(options));
    parserResult.WithNotParsed<Options>(errs =>
    {
        var helpText = HelpText.AutoBuild(parserResult, h =>
        {
            return HelpText.DefaultParsingErrorsHandler(parserResult, h);
        }, e =>
        {
            return e;
        });
        Console.WriteLine(helpText);
        ReturnErrorCode = ErrorCode.CommandLineArguments;
    });

    return (int)ReturnErrorCode;
}

我的查询与这行代码有关:

parserResult.WithParsed<Options>(options => OnSuccessfulParse(options));

我了解=> options的值为Lambda Expression 右侧的值表达式

究竟是什么OnSuccessfulParse?为什么编译?它工作得非常好。但它是什么?

我不知道这是否有帮助:

Definition of WithParsed

我可能会因为对此的理解而咆哮错误的树。我承认我正在努力解决这个问题。任何解释都赞赏。

我看到了几个问题,但在我的情况下无法解释。

更新

private static void OnSuccessfulParse(Options options) 声明是:

WithParsed

提供了/etc/docker/daemon.json代码here

3 个答案:

答案 0 :(得分:2)

这是表示功能块的C#(。Net)方式。 基本上Action<Type>是一个可调用的类型,大致意味着pass an instance of Type in and execute the block

E.g。我们可以写

public void Do(){
  this.CallStuff(s => Console.WriteLine(s)); // or you can use a method group and do this.CallStuff(Console.WriteLine);
}

public void CallStuff(Action<string> action){
  var @string = "fancy!";
  action(@string);
}

在这种情况下,s类型为string

在您的示例中,某处定义了一个名为Options的类型,并将其传递给某个操作。

此外,如果查看反编译代码,传递给操作的匿名方法块将被编译为类中的静态匿名类型(因为c#不支持动态代码块,例如obj-c)。

另一件需要关注的事情是Func<out type> - &gt;这些与Action<>基本相同,只是泛型定义中的LAST类型是它们返回的类型。

UPD @elgonzo提出了一个好点 - Action<>Func<>实际上只是代表;这意味着您可以定义一个真正的方法并将其作为Action或Func传递,然后不会编译匿名静态类。

然而在实践中你会看到很多代码定义了那些内联,然后内联代码块需要驻留在某个方法中,所以编译器将它放入statis匿名类中。

答案 1 :(得分:2)

Lambda表达式是Action<Options>类型的委托。它是从解析器到您的代码的回调,通知您解析已成功,并传递给您作为解析结果获得的Options对象。

options而言,它只是您为要传递到OnSuccessfulParse方法的参数而选择的名称。这里完全没有必要 - 这个方法组等效调用将编译并运行相同:

parserResult.WithParsed<Options>(OnSuccessfulParse);

以下是来自this questionWithParsed<T>方法的定义:

public static ParserResult<T> WithParsed<T>(this ParserResult<T> result, Action<T> action)
{
    var parsed = result as Parsed<T>;
    if (parsed != null) {
        action(parsed.Value);
    }
    return result;
}

此方法相当简单:它需要解析结果,尝试将其转换为成功的解析,如果转换有效,则调用您提供的委托。 WithNotParsed<T>方法转换为不成功的NotParsed<T>结果,并在转换有效时进行调用。

答案 2 :(得分:0)

  

选项究竟是什么?

options是由lambda表达式

表示的委托的i / p参数
  

为什么要编译?

仅仅因为它遵循编译器的所有语法和语义规则;)像(x)=>x+1是lambda表达式来表示Func<int,int>(可以有另一个委托来匹配相同的签名)

如果您的方法期望Func<int,int>作为参数和参数传递的是(x)=>x+1,那么编译器会将其推断为类型为int的x。编译的IL代码相当于将delegate的实例作为方法的参数传递。喜欢:

call((x)=>x+1)将编译为call(new Func<int,int>(myMethod)),其中调用方法定义为:

void Call(Func<int,int> someparam) {} 
  

但它是什么?

我认为以上回复应该已经解决了这个问题。