Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get an extension method to change the original object?

I want to be able to write extension methods so that I can say:

lines.ForceSpaceGroupsToBeTabs(); 

instead of:

lines = lines.ForceSpaceGroupsToBeTabs(); 

However, the following code currently outputs:

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

instead of:

Tone TTtwo 

What do I have to change in the following code to make it output:

Tone TTtwo 

(note that for visibility, . = 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;         }     } } 
like image 337
Edward Tanguay Avatar asked Feb 24 '10 14:02

Edward Tanguay


People also ask

Can you add extension methods to an existing static class?

There's no way to add them currently because the feature doesn't exist in C#.

What is correct extension method?

Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are static methods, but they're called as if they were instance methods on the extended type.

How do you call an extension method?

To define and call the extension methodDefine a static class to contain the extension method. The class must be visible to client code. For more information about accessibility rules, see Access Modifiers. Implement the extension method as a static method with at least the same visibility as the containing class.

How can the ambiguous extension method be resolved?

Ambiguity can be resolved if concurrent namespaces which have extension methods with same name, are included at different levels (most inner included namespace will have priority).


2 Answers

You have to modify the contents of the List<string> passed to the extension method, not the variable that holds the reference to the list:

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");     } } 
like image 155
dtb Avatar answered Sep 30 '22 11:09

dtb


You'd have to change the contents of the original list - just reassigning the parameter to have a different value isn't going to do it. Something like this:

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

It's worth noting that this has nothing to do with extension methods. Imagine you'd just called:

Helpers.ForceSpaceGroupsToBeTabs(lines); 

... because that's what the code is effectively translated into. There's nothing special about the fact that it's an extension method; if you change the code so that the "normal" static method will work, then it'll work as an extension method too. As noted in the comments, one thing you can't do with an extension method is make the first parameter a ref parameter.

(EDIT: I realise this is the exact same code that dtb posted, although we arrived there independently. I'm keeping this answer anyway, as it's got more than code.)

like image 32
Jon Skeet Avatar answered Sep 30 '22 12:09

Jon Skeet