【问题标题】:Find matching element in list using delegate and lambda使用委托和 lambda 在列表中查找匹配元素
【发布时间】:2015-02-19 04:37:57
【问题描述】:

编辑

我最初的问题不是很清楚,所以我想现在改一下。如果我仍然错过标记,请告诉我。

本质上,我正在尝试返回一个新字符串,其中所有用括号括起来的子字符串都已替换为列表中对象的字符串。作为一个抽象的例子,我想做如下的事情:

public class MyType () : IEquatable <Property>
{

    public string id;

    public override String ToString()
    {

        return id;
    }

    public bool Equals ( MyType other )
    {

        if ( other is MyType == false )
        {

            return false;
        }

        return this.id == other.id;
    }
}



List<MyType> listOfCustomTypes = new List<MyType> ();

return Regex.Replace ( originalString, "{(.*?)}", d => listOfCustomTypes.Where ( t => t.id == d.Groups[1].Value ).FirstOrDefault ());

具体来说,我遇到的问题或错误是Cannot convert lambda expression to delegate type (System.Text.RegularExpressions.MatchEvaluator) because some of the return types in the block are not implicitly convertible to the delegate return type

我假设它不允许在委托中使用返回类型,或者其他什么,因为我通常可以访问它的属性,或者转换为字符串。

我可能仍然设法弄乱了我的问题,所以如果它有帮助,我的完整项目可以看到here,这个问题的相关文件是here(具体行是 161)。


原始问题

我正在尝试学习如何使用委托和 lambda,并且以典型的方式,我无法咀嚼。在下面的代码 sn-p 中,我定义了一个类,其中包含一个类列表。在另一个函数中,我尝试使用字符串来查找列表项,并从该项中获取值。

[XmlRoot ( "Replacers" )]
public class Replacers
{

    [XmlElement ( "Property" )]
    public List<Property> properties = new List<Property> ();

    [XmlIgnore]
    public static Replacers replacers;
}


public class Property : IEquatable <Property>
{

    [XmlAttribute ( "id" )]
    public string id;

    [XmlElement ( "Value" )]
    public List<Value> propertyValue = new List<Value> ();


    public override String ToString()
    {

        return id;
    }

    public bool Equals ( Property other )
    {

        return this.id == other.id && this.propertyValue == other.propertyValue;
    }
}



public static class GetVariable
{

    public static string FromUser ( string originalString )
    {

        try
        {

            //return Regex.Replace ( originalString, "{(.*?)}", m => Replacers.replacers.properties.FindIndex ( m.Groups[1].Value ) );
        } catch ( Exception e )
        {

            return "ERROR: Unable to find '" + Regex.Match ( originalString, "{(.*?)}" ) + "'";
        }
    }
}

上面注释掉的行是我试图弄清楚。如何将与模式 {(.*?)} 匹配的任何内容替换为同名列表项中的值。

感谢您花时间考虑我的问题!

TL;DR:

如何使用 lambda 迭代列表,其中迭代返回实际的列表项?例如,我想做类似的事情:Regex.Replace ( input, pattern, m =&gt; myList.Where(listItem.identifier == m)。我觉得我的问题不是很清楚,所以如果您感到困惑,请询问。谢谢!

【问题讨论】:

    标签: c# list lambda delegates


    【解决方案1】:

    考虑这个例子:

    var foos = new[] { "aaa", "aba", "aca" };
    
    var bars = foos.Where(f => f.Contains("b")).Select(f => Regex.Replace(f, "b", "d"));
    
    foreach (var bar in bars)
        Console.WriteLine(bar);
    
    // Output:
    ada
    

    编辑:我会尝试解决您的评论

    lambda 只是委托(一种类型化方法)的简写。

    您可能已经习惯了 int、string、double、Animal 等类型。

    好吧,只需将该概念扩展到方法签名即可。

    您可以将任何方法签名视为一种类型。

    这是一个返回 bool 并以 int 作为参数的方法:

    bool A(int i) { ... }
    

    所以签名可以看成一个类型。

    lambda 是它的简写。这是一个 lambda,它接受一个 int,并返回一个 bool,就像上面的方法签名一样:

    (x) => x % 2 == 0
    

    Linq 扩展方法(Where()、Select() 等)都采用某种委托类型或 lambda 表达式。

    myCollection.Where(x => x % 2 == 0).Where(x => x > 10).Select(x => x * 2);
    

    美妙之处在于您可以继续链接这些扩展方法,如果您愿意,每个方法都可以成为额外的过滤器。

    Select() 很特别,因为它是一个投影操作(它转换集合中的项目)。你可以在这里看到它采用了这个奇怪的参数:

    Func<string, string> // or something like that, depends on the types in your collection
    

    Func 有点像代表,但在更一般的意义上。这很容易理解。第一个类型参数是输入参数(想想方法的参数),最后一个是输出(想想方法的返回类型)

    Func<in, in, in, out>
    

    考虑一下:

    // Here's a method signature
    bool MyMethod(int a, int b)
    
    // Here's a lambda of the same delegate type
    (a, b) => a == b
    
    // Here's a Func being assigned that lambda
    Func<int, int, bool> func = (a, b) => a == b;
    

    【讨论】:

    • 我对代表和 lambda 不是很有经验,所以如果这是一个愚蠢的问题,请原谅,但是使用您提供的示例,我将如何搜索 f,使用包含,但所有{(.*?)} 的匹配项?从本质上讲,我不想寻找“b”,而是想搜索用大括号括起来的每个字符实例,并使用它。
    • 感谢您向我解释这些概念,深入了解代表的工作方式(以及它们是什么)肯定会帮助我理解如何使用它们!我将花一些时间将其应用于我的问题,之后我会回来将您的答案标记为正确(暂时推迟,以防其他人有更多好的提示或建议)。再次感谢!
    • 酷,我可能没有具体回答您的问题(因为我不确定您要问什么)。没关系!用知识武装自己比在网站上收集绿色复选标记重要得多!
    • 感谢您的帮助,根据您的建议,我能够弄清楚如何解决我的问题!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-24
    • 1970-01-01
    • 2013-12-06
    • 1970-01-01
    • 2023-03-24
    • 2016-08-14
    相关资源
    最近更新 更多