C# 林克兰姆达弗雷奇

C# 林克兰姆达弗雷奇,c#,linq,lambda,C#,Linq,Lambda,试图在数组中包装每个字符串,但它不起作用,这意味着foreach循环,请解释原因 string s = "keepsakes,table runners,outdoor accessories"; List<string> keys = s.Split(',').ToList(); keys.ForEach(x => x = String.Concat("%", x, "%")); s = String.Join(",", keys); Console.WriteLine(s)

试图在数组中包装每个字符串,但它不起作用,这意味着foreach循环,请解释原因

string s = "keepsakes,table runners,outdoor accessories";
List<string> keys = s.Split(',').ToList();
keys.ForEach(x => x = String.Concat("%", x, "%"));
s = String.Join(",", keys);
Console.WriteLine(s); 
和func

        string s = "keepsakes,table runners,outdoor accessories";
        List<MyItems> keys = s.Split(',').ToList().Select(x => new MyItems(){ Item = x }).ToList();
        keys.ForEach(x => x.Item = String.Concat("%", x.Item, "%"));
        s = String.Join(",", keys.Select(x => x.Item).ToList());
        Console.WriteLine(s);
string s=“纪念品、桌椅、户外配件”;
列表键=s.Split(',').ToList().Select(x=>newmyitems(){Item=x}).ToList();
keys.ForEach(x=>x.Item=String.Concat(“%”,x.Item,“%”);
s=String.Join(“,”,keys.Select(x=>x.Item.ToList());
控制台。写入线(s);

您不是在
ForEach
中修改列表,您只是在创建分配给局部变量
x
的字符串,然后将其丢弃。您可以为-循环使用

for(int i = 0; i < keys.Count; i++)
{
    keys[i] = String.Concat("%", keys[i], "%");
}
List.ForEach
不能用于更改列表的内容。您可以创建新列表,也可以使用
for
循环

keys = keys.Select(x => "%" + x + "%").ToList();

for(int i=0;i
您可以使用
Join
选择
格式

string s = "keepsakes,table runners,outdoor accessories";

var output = string.Join(",", s.Split(',').Select(x => string.Format("%{0}%", x)));

您可以做得更简单:将每个逗号替换为
%,%%

string s = "keepsakes,table runners,outdoor accessories";
string s2 = "%" + s.Replace("," , "%,%") + "%";

正如其他人所指出的,传递给
列表的lambda.ForEach
不返回值

LINQ是惰性的,但
String.Join
将强制枚举:

var res = String.Join(",", input.Split(',').Select(s => "%" + s + "%"));

ForEach不会更改字符串列表,它只会使用每个字符串执行一个操作。相反,您可以这样做:

string s = "keepsakes,table runners,outdoor accessories";
List<string> keys = s.Split(',').Select(x => String.Concat("%", x, "%")).ToList();
s = String.Join(",", keys);
Console.WriteLine(s);
string s=“纪念品、桌椅、户外配件”;
列表键=s.Split(',')。选择(x=>String.Concat(“%”,x,“%”)。ToList();
s=String.Join(“,”键);
控制台。写入线(s);
只是另一种方法(没有lambdas):


另一种方法是使用
Regex
代替LINQ:

string s = "keepsakes,table runners,outdoor accessories";
string pattern = "\\,+";
string replacement = "%,";

Regex rgx = new Regex(pattern);
string result = string.Format("%{0}%", rgx.Replace(s, replacement));
编辑:

它之所以使用类来分配字符串,是因为在第一个实例中使用foreach时:

keys.ForEach(x => x = String.Concat("%", x, "%"));
x、 键的元素是一个字符串,是一个通过值传递给函数ForEach的引用。以此为例:

var myString = "I'm a string";

Console.WriteLine(myString);

ChangeValue(myString);

Console.WriteLine(myString);

void ChangeValue(string s)
{
    s = "something else";
}
如果运行该代码段,您将看到
myString
不会在方法ChangeValue中更改,因为我们正在尝试替换引用。方法
ForEach
也会发生同样的情况,这是您无法在
ForEach
中更改列表值的主要原因

相反,如果您这样做:

class MyClass{
    public string aString;
 }

void ChangeValue(MyClass s)
{
    s.aString = "something else";
}

 var myClass = new MyClass();
 myClass.aString =  "I'm a string";

 Console.WriteLine(myClass.aString);

 ChangeValue(myClass);

 Console.WriteLine(myClass.aString);

您确认在第二个
控制台.WriteLine
中,字段aString的值将更改为“其他内容”。这是一个很好的解释,说明了引用类型是如何通过值传递的。

“它不起作用”-到底发生了什么?实际产量是多少?还有,你所说的“数组”是什么意思?我更新了我的答案,请检查一下,这是唯一一个有解释的答案!请,如果你可以-看看更新的答案除此之外,第二个代码段是有效的,所以如果你不理解为什么它与类的属性一起工作,我不理解“有人能回答为什么这个工作而不是在…”。原因是类
MyItems
是引用类型,并且您正在修改
List.ForEach
中每个引用的属性。通过这种方式,您可以修改列表中的原始对象,这与您尝试替换引用本身的第一种方法不同answer@DaveBish:您的更新不正确。第二个代码段与第一个代码段相反,我想OP想知道为什么。原因与字符串的不变性无关,而是他更改了引用类型的属性,而不是试图替换
列表中的整个引用。ForEach
。请,如果可以-查看更新的应答请,如果可以-查看更新的应答请,如果可以-查看更新的应答请,如果可以,请查看更新的答案
string s = "keepsakes,table runners,outdoor accessories";
string pattern = "\\,+";
string replacement = "%,";

Regex rgx = new Regex(pattern);
string result = string.Format("%{0}%", rgx.Replace(s, replacement));
keys.ForEach(x => x = String.Concat("%", x, "%"));
var myString = "I'm a string";

Console.WriteLine(myString);

ChangeValue(myString);

Console.WriteLine(myString);

void ChangeValue(string s)
{
    s = "something else";
}
class MyClass{
    public string aString;
 }

void ChangeValue(MyClass s)
{
    s.aString = "something else";
}

 var myClass = new MyClass();
 myClass.aString =  "I'm a string";

 Console.WriteLine(myClass.aString);

 ChangeValue(myClass);

 Console.WriteLine(myClass.aString);