使用委托和 lambda 在列表中查找匹配元素

Find matching element in list using delegate and lambda

编辑

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

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

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

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

我可能还是把我的问题弄乱了,所以如果有帮助,我的完整项目可以看到here, and the relevant file for this question is here(具体行是161)。


原问题

我正在努力学习如何使用委托和 lambda,并且以典型的方式,咬牙切齿。在下面的代码片段中,我定义了一个 class,它包含一个 class 的列表。在另一个函数中,我尝试使用字符串查找列表项,并从该项中获取值。

[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, "{(.*?)}" ) + "'";
        }
    }
}

上面注释掉的那一行是我想弄明白的。如何用同名列表项中的值替换与模式 {(.*?)} 匹配的任何内容。

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

长话短说:

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

考虑这个例子:

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 只是 shorthand 委托(类型化方法)。

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

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

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

这里有一个方法,return是一个 bool,并接受一个 int 作为参数:

bool A(int i) { ... }

所以签名可以看作是一种类型。

lambda 是一个 shorthand。这是一个 lambda,它接受一个 int,return 是一个 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

A Func 有点像委托,但更通用。这很容易理解。第一个类型参数是输入参数(想想方法的参数),最后一个是输出(想想方法的 return 类型)

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;