¿Cómo puedo obtener un método de extensión para cambiar el objeto original?

Quiero poder escribir métodos de extensión para poder decir:

lines.ForceSpaceGroupsToBeTabs(); 

en lugar de:

 lines = lines.ForceSpaceGroupsToBeTabs(); 

Sin embargo, el siguiente código muestra actualmente:

 ....one ........two 

en lugar de:

 Tone TTtwo 

¿Qué tengo que cambiar en el siguiente código para que salga?

 Tone TTtwo 

(tenga en cuenta que para la visibilidad,. . = 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; } } } 

Debe modificar los contenidos de la List pasados ​​al método de extensión, no la variable que contiene la referencia a la lista:

 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"); } } 

Tendría que cambiar el contenido de la lista original; solo reasignar el parámetro para que tenga un valor diferente no lo va a hacer. Algo como esto:

 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"); } } 

Vale la pena señalar que esto no tiene nada que ver con los métodos de extensión . Imagina que acabas de llamar:

 Helpers.ForceSpaceGroupsToBeTabs(lines); 

... porque a eso es a lo que se traduce efectivamente el código. No hay nada de especial en el hecho de que es un método de extensión; si cambias el código para que funcione el método estático "normal", también funcionará como un método de extensión. Como se señaló en los comentarios, una cosa que no se puede hacer con un método de extensión es hacer que el primer parámetro sea un parámetro ref .

(EDITAR: me doy cuenta de que este es exactamente el mismo código que dtb publicado, aunque llegamos allí de forma independiente. De todos modos, mantengo esta respuesta, ya que tiene más de código).

Si es un tipo de referencia, tendría que cambiar su contenido. Si es un tipo de valor que está pasando, no tiene suerte. La misma existencia de los métodos de extensión se pone en marcha para apoyar paradigmas funcionales en C #, y esos paradigmas funcionales, por su propia esencia, tienden a la inmutabilidad de los tipos, de ahí la incapacidad de cambiar el valor del cual se llama el método de extensión.

En otras palabras, si bien puede hacerlo, puede no estar de acuerdo con el “espíritu” de la progtwigción funcional.