我希望能够编写扩展方法,以便我可以说:
lines.ForceSpaceGroupsToBeTabs();
而不是:
lines = lines.ForceSpaceGroupsToBeTabs();
但是,以下代码目前输出:
....one
........two
而不是:
Tone
TTtwo
我需要在以下代码中更改以进行输出:
Tone
TTtwo
(请注意,可见度. = space, T = \t
):
using System;
using System.Collections.Generic;
namespace TestExtended82343
{
class Program
{
static void Main(string[] args)
{
List<string> lines = new List<string>();
lines.Add("....one");
lines.Add("........two");
lines.ForceSpaceGroupsToBeTabs();
lines.ForEach(l => Console.WriteLine(l));
Console.ReadLine();
}
}
public static class Helpers
{
public static void ForceSpaceGroupsToBeTabs(this List<string> originalLines)
{
string spaceGroup = new String('.', 4);
List<string> lines = new List<string>();
foreach (var originalLine in originalLines)
{
lines.Add(originalLine.Replace(spaceGroup, "T"));
}
originalLines = lines;
}
}
}
答案 0 :(得分:39)
您必须修改传递给扩展方法的List<string>
的内容,而不是包含对列表的引用的变量:
public static void ForceSpaceGroupsToBeTabs(this List<string> lines)
{
string spaceGroup = new String('.', 4);
for (int i = 0; i < lines.Count; i++)
{
lines[i] = lines[i].Replace(spaceGroup, "T");
}
}
答案 1 :(得分:15)
您必须更改原始列表的内容 - 只需重新分配参数以使其具有不同的值即可。像这样:
public static void ForceSpaceGroupsToBeTabs(this List<string> lines)
{
string spaceGroup = new String('.', 4);
for (int i = 0; i < lines.Count; i++)
{
lines[i] = lines[i].Replace(spaceGroup, "T");
}
}
值得注意的是,这与无关的扩展方法。想象一下,你刚刚打过电话:
Helpers.ForceSpaceGroupsToBeTabs(lines);
...因为这就是代码被有效翻译成的东西。关于它是一种扩展方法这一事实并没有什么特别之处;如果你更改代码以便“普通”静态方法可以工作,那么它也可以作为扩展方法。如评论中所述,无法使用扩展方法做的一件事是将第一个参数设为ref
参数。
(编辑:我意识到这与dtb发布的完全相同的代码,虽然我们是独立到达那里的。无论如何我仍然保留这个答案,因为它不仅仅是代码。)
答案 2 :(得分:12)
如果是引用类型,则必须更改其内容。如果它是你传入的价值类型,那你就不走运了。扩展方法的存在是为了支持C#中的功能范例,而这些功能范例本质上倾向于类型的不变性,因此无法改变调用扩展方法的值。
换句话说,虽然你可以这样做,但它可能不符合函数式编程的“精神”。