C# Lambda表达式转到语法

C# Lambda表达式转到语法,c#,C#,我很难理解下面的Lambda表达式。如果我没弄错的话,=>操作符的意思是 我有一个从xps生成pdf的方法。这个方法是否意味着运行GeneratePdf方法,然后对结果变量pdf执行任何操作 public void GenerateCurrentPdf(FooResponse response) { if (response.Success) { GeneratePdf(pdf => { var attachInfo

我很难理解下面的Lambda表达式。如果我没弄错的话,=>操作符的意思是

我有一个从xps生成pdf的方法。这个方法是否意味着运行GeneratePdf方法,然后对结果变量pdf执行任何操作

public void GenerateCurrentPdf(FooResponse response)
{
    if (response.Success)
    {
        GeneratePdf(pdf =>
        {
            var attachInfo = new AttachmentInformation
            {
                AttachmentId = Guid.NewGuid(),
                AttachmentNote = "New Version",
                FileName = pdf.FileName,
                ImageByte = pdf.FileBytes
            };

            try
            {
                /// do something here
            }
            catch (Exception ex)
            {
                ///log error
            }
        });
    }
}
GeneratePdf方法让我更加困惑,因为它没有从调用方法传递任何参数。我在MSDN中查找操作,它说“封装了一个没有参数且不返回值的方法。”但GeneratePdf的末尾再次调用GeneratePdf方法

public void GeneratePdf(Action<FileAttachment> onComplete)
{
    string xpsPath = Environment.CurrentDirectory + "\\" + Id + ".xps";

    SaveAsXps(xpsPath, () =>
    {
        string pdfPath = Environment.CurrentDirectory + "\\" + Id + ".pdf";
        string registrationCode = ConfigurationManager.AppSettings.Get("NiXPS:RegistrationCode");
        Converter.Initialize(registrationCode);
        var outStream = new MemoryStream();
        Converter.XpsToPdf(new MemoryStream(FileToByteArray(xpsPath)), outStream);
        File.Delete(xpsPath);
        byte[] bytes = outStream.ToArray();        
        var attachment = new FileAttachment
        {
            ContentType = "application/pdf",
            FileBytes = bytes,
            FileName = fooId + ".pdf"          
        };
        onComplete(attachment);
    });
}
完整的语法是(参数列表)=>{methodbody}

如果只有一个参数,则可以放弃()

如果您只想返回一个值,您可以放弃{}并只写结果值

以下是等效的:

a => a + 1
(a) => a + 1
(a) => { return a+1; }

=>
并不意味着“转到”。正如您所说,它是.NET lambda语法的一部分。在本例中,
pdf=>(stuff)
意味着
pdf
是一个没有名称的方法的参数,
=>
后面的块是该方法的内容

Action
是一种引用lambda的方法,该lambda只接受一个参数,不返回任何内容

这个方法是否意味着运行GeneratePdf方法,然后对 结果变量pdf

public void GenerateCurrentPdf(FooResponse response)
{
    if (response.Success)
    {
        GeneratePdf(pdf =>
        {
            var attachInfo = new AttachmentInformation
            {
                AttachmentId = Guid.NewGuid(),
                AttachmentNote = "New Version",
                FileName = pdf.FileName,
                ImageByte = pdf.FileBytes
            };

            try
            {
                /// do something here
            }
            catch (Exception ex)
            {
                ///log error
            }
        });
    }
}
对。事实上,GeneratePdf可以选择根本不执行代码

你可以这样想:

public class MyCode
{
    public void MyAction(FileAttachment pdf)
    {
            var attachInfo = new AttachmentInformation
            {
                AttachmentId = Guid.NewGuid(),
                AttachmentNote = "New Version",
                FileName = pdf.FileName,
                ImageByte = pdf.FileBytes
            };

            try
            {
                /// do something here
            }
            catch (Exception ex)
            {
                ///log error
            }
    }
}


public void GeneratePdf(MyCode onComplete)
{
    string xpsPath = Environment.CurrentDirectory + "\\" + Id + ".xps";

    SaveAsXps(xpsPath, () =>
    {
        string pdfPath = Environment.CurrentDirectory + "\\" + Id + ".pdf";
        string registrationCode = ConfigurationManager.AppSettings.Get("NiXPS:RegistrationCode");
        Converter.Initialize(registrationCode);
        var outStream = new MemoryStream();
        Converter.XpsToPdf(new MemoryStream(FileToByteArray(xpsPath)), outStream);
        File.Delete(xpsPath);
        byte[] bytes = outStream.ToArray();        
        var attachment = new FileAttachment
        {
            ContentType = "application/pdf",
            FileBytes = bytes,
            FileName = fooId + ".pdf"          
        };
        onComplete.MyAction(attachment);
    });
}

public void GenerateCurrentPdf(FooResponse response)
{
    if (response.Success)
    {
        var act = new MyCode();
        GeneratePdf(act);
    }
}
这在功能上是相似的,但在时间上有一些细微的差别

GeneratePdf方法让我更加困惑,因为它没有通过 调用方法中的任何参数

它正在从
SaveXps
中的代码接收
FileAttachment
对象:

var attachment = new FileAttachment
{
    ContentType = "application/pdf",
    FileBytes = bytes,
    FileName = fooId + ".pdf"          
};
onComplete(attachment)

但请记住,您不能确定何时或是否执行任何代码。
SaveXps
方法通过选择是否执行传递给它的lambda代码来控制自身的执行,当到达
onComplete(attachment)
时,该方法引用并导致执行外部lambda代码。

以下代码是表示
操作的lambda

我会用英语声明,它会翻译成编译器,将名为
pdf
的参数传递给以下委托(它可以推断类型)

大致相当于:

private void MyCallback(FileAttachment pdf)
{
    // ...
}

行动
定义为
公共代表无效行动(T obj)。简单地说,它本质上是一个方便的内置委托定义,用于接受任何类型的泛型参数的void函数。

一个惯例实际上是将
=>
发音为“goes to”。所以说“去”并不是“错”,只是理解短语“去”的意思。谢谢你的解释。我添加了SaveAsXps。
private void MyCallback(FileAttachment pdf)
{
    // ...
}