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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了传递给这个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));

我理解,使用Lambda Expression=>左边的值是值,右边的值是表达式。

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

我不知道这是否有帮助:

Definition of WithParsed

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

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

Update

OnSuccessfulParse声明是:

private static void OnSuccessfulParse(Options options)

WithParsed代码提供here

答案

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

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

parserResult.WithParsed<Options>(OnSuccessfulParse);

以下是来自WithParsed<T>github project方法的定义:

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>结果,并在演员表有效时进行调用。

另一答案

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

例如。我们可以写

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> - >这些与Action<>基本相同,只是泛型定义中的LAST类型是它们返回的类型。

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

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

另一答案

究竟是什么选择?

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) {} 

但它是什么?

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

以上是关于传递给这个lambda表达式的值是多少?的主要内容,如果未能解决你的问题,请参考以下文章

C# - 如何获取传递的 lambda 表达式的值

lambda表达式

分配给On Error Resume Next的变量的值是多少?

Lambda 表达式以及如何组合它们?

Kotlin学习与实践 Lambda

C++ lambda 表达式的生命周期是多少?