如何获得更改原始对象的扩展方法?

我希望能够编写扩展方法,以便我可以说:

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 lines = new List(); 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 originalLines) { string spaceGroup = new String('.', 4); List lines = new List(); foreach (var originalLine in originalLines) { lines.Add(originalLine.Replace(spaceGroup, "T")); } originalLines = lines; } } } 

您必须修改传递给扩展方法的List的内容,而不是包含对列表的引用的变量:

 public static void ForceSpaceGroupsToBeTabs(this List lines) { string spaceGroup = new String('.', 4); for (int i = 0; i < lines.Count; i++) { lines[i] = lines[i].Replace(spaceGroup, "T"); } } 

您必须更改原始列表的内容 – 只需重新分配参数以使其具有不同的值即可。 像这样的东西:

 public static void ForceSpaceGroupsToBeTabs(this List 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发布的完全相同的代码,虽然我们是独立到达那里的。无论如何我仍然保留这个答案,因为它不仅仅是代码。)

如果它是引用类型,则必须更改其内容。 如果它是你传入的价值类型,那你就不走运了。 扩展方法的存在是为了支持C#中的函数范式,而这些函数范例本质上倾向于类型的不变性,因此无法改变调用扩展方法的值。

换句话说,虽然你可以做到,但它可能不符合函数式编程的“精神”。