需要帮助学习更多使用lambda,如以下方法

时间:2019-07-17 14:23:12

标签: c# lambda

我以前从未使用过lambda或linq;但我真的很想学习如何。我了解Linq,我用它来查询一些非常简单的lambda表达式的集合,但是我看到其他编码器几乎在每种编码情况下都使用lambda。我不完全了解它们,这有点令人沮丧。

因此,我希望获得一些帮助,以帮助我转换我刚刚编写的在任何可以使用lambda的方法。我不是在尝试优化该方法,我只是很好奇您可以在其中使用lambda,并且如果您能简要说明为什么在您使用lambda的地方,我将不胜感激。

我了解如何使用委托和匿名委托,我只是从不使用Lambda。但我想更改它。

 `public ActionResult xmethod(int vid,int pid)
        {
            ProRep pr = new ProRep();
            List<ProImage> pi = new List<ProImage>();
            pi = pr.somemethod(vid,pid);
            return PartialView("zmethod", pi);
        }`

1 个答案:

答案 0 :(得分:0)

GetFileOutputPath函数内部没有任何东西真正表明需要lambda。这是因为代码中没有方法或函数要求您传递函数。只要将函数作为参数传递给某些东西,就会使用Lambda。

如果您想更好地了解lambda,也许最好开始构建自己想要了解的linq方法的原始版本。考虑一下这个函数,它接受一个函数作为它的第二个参数:

List<int> filterList (List<int> list, Func<int,bool> filterFunc) {
    var result = new List<int>();
    foreach(var entry in list) {
        if(filterFunc(entry)) {
            result.Add(entry);
        }
    }
    return result;
}

您可以将其与如下所示的lambda一起使用:

var list = new List<int> { 1, 2, 3 };
var filtered = filterList(list, entry => entry >= 2);
// [2,3]

在这里您可以看到lambda的一大优势:您无需在'filterList'中使用该函数即可创建该函数。您可以先创建函数,但是,如果它是一次性使用且非常简单的函数,则只需在将其作为参数传递的同时将其定义为负即可。


编辑: 要解决OP真正在其代码中强制使用lambda的愿望。

您使用String.Format 6次。您对参数的使用是如此之多,以至于实际上不建议使用lambda。不过,为了满足您的好奇心,让我们开始吧!

以下是使用String.Format的两种类似方法:

String.Format(@"{0}\{1}_{2}", filePath, fileName, fileTimeString);
String.Format(@"{0}{1}_{2}", filePath, fileName, fileTimeString);

除第一个参数外,所有参数均相同。因此,让我们创建一个作为函数的变量。我们将使用lambda语法对其进行定义:

Func<string,string> formatInput = 
    format => String.Format(format, filePath, fileName, fileTimeString);

// <string,string> means that the first (and only) parameter, eventually 
// called 'format', is a string, and that the output is a string.  

现在您可以执行以下操作:

formatInput(@"{0}\{1}_{2}");
formatInput(@"{0}{1}_{2}");

是的,'formatInput'可以访问您的本地范围,因此即使您没有将它们作为参数传递,它也知道'filePath','fileName'和'fileTimeString'。

将您对String.Format的所有使用替换为3个本地定义的函数,您的代码应如下所示:

private string GetFileOutputPath(string filePath, string fileName, string fileExtension, DateTime fileTime, string fileTimeFormat) {

    string outputFilePath = string.Empty;
    string fileTimeString = fileTime.ToString(fileTimeFormat);

    Func<string,string> formatInput = format => String.Format(format, filePath, fileName, fileTimeString);
    Func<string,string> formatOutput = format => String.Format(format, outputFilePath, fileExtension);
    Func<string,int,string> formatOutputI = (format, i) => String.Format(format, outputFilePath, i, fileExtension);

    //Create initial output filepath, before we check for dups.
    if (filePath[filePath.Length - 1] != '\\')
        outputFilePath = formatInput(@"{0}\{1}_{2}");
    else
        outputFilePath = formatInput(@"{0}{1}_{2}");

    //In the case we already have the file in the directory.  
    if (File.Exists(formatOutput("{0}.{1}"))) {
        //Iterate through the directory until we find a file name we can use .. using the microsoft convention of "filename(1).txt".
        int i;
        for (i = 1; File.Exists(formatOutputI("{0}({1}).{2}", i)); ++i);
        outputFilePath = formatOutputI("{0}({1}).{2}", i);
    }
    else {
        outputFilePath = formatOutput("{0}.{1}");
    }

    return outputFilePath;
}

尽管在您的示例中本地定义的函数没有什么用,但如果我认为它们会提高可读性和DRY问题,并且不希望使用正式函数或方法,那么我不害怕使用它们。我猜您的同事不一定只是为了展示自己而使用lambda。它们可以使您的代码更加优雅。即使在我为您重新编写的代码中(不建议使用lambda),我也会原谅使用它们的编码器。