在string[].Foreach()中,T[]参数是什么意思?

3

我刚开始使用Lambda表达式等相关知识。然而,在这种情况下,我不知道需要提供什么参数。

我试图修改字符串以替换字典中所有条目的值,这并不是很花哨,我可以使用简单的foreach循环来实现,但我正在尝试将其作为学习练习。

到目前为止,我的代码如下:

        string maskString = Masks[alias];
        Regex regex = new Regex(@"({[\w+|\d]+})");
        MatchCollection matches = regex.Matches(maskString);
        string[] constants = matches.Cast<Match>().Select(m => m.Value).ToArray();
        string maskedString = "";
        if (constants.All(constant => Constants.ContainsKey(constant)))
        {
            constants.ForEach(constant => maskedString = maskedString.Replace(constant, Constants[constant]));
        }

然而,我收到了这个错误:There is no argument given that corresponds to the required formal parameter 'action' of 'Array.ForEach<T>(T[], Action<T>)'。在我的看法中,我以lambda表达式的形式提供了操作,但我不知道为什么它需要另一个数组或者我应该给它什么数组。

我尝试过提供nullstring[]new [] {typeof(string)},但这些只会引起更多的错误。

是否可能使用这种结构来进行此操作,或者使用传统的foreach循环更实际?


3
Array.ForEach不是扩展方法(它只是Array的静态方法),所以使用方式如下:Array.ForEach(constants, constant => maskedString = maskedString.Replace(constant, Constants[constant])); 无论如何,在涉及“副作用”时,我更喜欢使用标准的foreach循环。 - digEmAll
保持简单和可维护。LINQ语句可能很有用,但也可能难以解释。 - Dan Wilson
@digEmAll 我注意到你评论之前,通过查看文档(https://msdn.microsoft.com/en-us/library/zecdkyw2(v=vs.110).aspx),我实际上在发布答案之前并没有看到这个评论,但还是谢谢!出于好奇,为什么它是大多数`IEnumerable<T>的扩展方法,但不是[]`? - ScottishTapWater
@JamesHughes 这根本不是扩展方法。对于 Array.ForEach,它是一个静态的非扩展方法。对于 List<T>.ForEach,它是一个常规实例方法。对于其他的 IEnumerable<T>,没有标准的 ForEach 可以调用,无论是扩展方法还是非扩展方法。 - user743382
@hvd 对,我同意你的观点。是我的错误。 - ScottishTapWater
2个回答

6

这似乎是对 .ForEach() 方法的错误使用,它是 Array 类的一个 static 方法,而不是扩展方法。有两种正确的方法来执行此操作:

第一种方法是使用 Array.ForEach() 静态方法,并将数组作为第一个参数:

Array.ForEach(constants,constant => maskedString = maskedString.Replace(constant, Constants[constant]));

其次,先将数组转换为List<T>:

constants.ToList().ForEach(constant => maskedString = maskedString.Replace(constant, Constants[constant]));

第二种方法不会修改原始数组,因此如果需要修改原始数组,则需要执行 myArray = myArray.ToList().ForEach().ToArray()。感谢Chris提供这个观点。

请注意,您的第二个代码将不会完美运行。它将创建一个新的List对象,然后对该对象进行操作。原始常量数组将不会被修改。相反,您需要执行constants = (your expression).ToArray(); - Chris
@Chris 我实际上并没有修改原始数组,我只是用它来修改一个单独的字符串,但这对于其他人阅读此内容是一个重要的澄清。 - ScottishTapWater
我的观点是,如果没有赋值语句,你的第二个操作就毫无意义。这不仅仅是“如果需要”的问题,因为如果不需要,你也可以不写代码。 - Chris
1
好的,谢谢伙计,没问题。我是楼主,我在其他人回答之前就解决了这个问题,所以我想发表我的解决方案,而不是删除这个问题。 - ScottishTapWater
哦,亲爱的。在我喝咖啡之前,我显然不应该在这里发表评论。 :) - Chris
显示剩余2条评论

2

任何时候都应该使用聚合函数:

maskedString = constants.Aggregate(maskedString, (current, constant ) => current.Replace(constant , Constants[constant]));

我喜欢这个... 我非常喜欢这个。谢谢! - ScottishTapWater
@JamesHughes 谢谢,您能否那么好心地将答案标记为解决方案 :) - Maksim Simkin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接