2

I'm trying to make a simple extension method, for the String class, which will allow me to supply text to be appended to an existing string variable with a newline character included:

string myStr = "Line 1";
myStr.AppendLine("Line 2");

This code should yield a string that prints as follows

Line 1
Line 2

Here's the code I wrote for it:

public static class StringExtensions
{
    public static void appendLine(this String str, string text)
    {
        str = str + text + Environment.NewLine;
    }
}

But when I call the code, the new text never gets appended to the original instance variable. How to achieve that?

Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
Jason O
  • 753
  • 9
  • 28
  • 2
    Strings are immutable, they can't be modified after they are created. You'd need to return a new string instead of void. – dmeglio May 23 '16 at 21:02
  • [C# string replace does not work](http://stackoverflow.com/questions/13277667/c-sharp-string-replace-does-not-work) is well known fact... You really can't do much about it. – Alexei Levenkov May 23 '16 at 21:05
  • Ahhh ok. I somehow missed that detail in my studies. Thanks! – Jason O May 23 '16 at 21:07

3 Answers3

6

You need to modify value of variable for this to work as strings are immutable (see public C# string replace does not work). Unfortunately there is no way to do it with extension method as ref is not allowed there:

 public static void appendLine(this ref String str, string text) // invalid

So the your options

  • regular method with ref

      public static void AppendLine(ref String str, string text)
      {
         str = str + text;
      }
    
  • return new value from extension method:

      public static string AppendLine(this String str, string text)
      {
         return str + text;
      }
    

Note: consider if StringBuilder works better for your case.

Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • 1
    Does the fact that a string is immutable matter here? Isn't the problem really just that an extension method can't be used with `ref`, and that the string (a reference type) is being passed by value? I'm asking because I honestly don't know. I was looking at @JonSkeet s answer [here](http://stackoverflow.com/questions/1096449/c-sharp-string-reference-type) – Jonesopolis May 23 '16 at 21:13
  • @Jonesopolis immutability does matter here - you can easily write similar extension method for `StringBuilder` and it would work the way OP wanted. Immutability prevents modification to instance (which extension methods *can* do) thus forcing one to modify what variable refers to (which extension methods *can not* do). – Alexei Levenkov May 23 '16 at 21:15
  • Good explanation, but none of the code in the question involves an attempt to mutate a string. – Tom Blodget May 23 '16 at 23:35
  • @TomBlodget I'm not sure what other interpretation one can make for "text to be appended to an existing string variable" rather than change existing string. Feel free to provide your own interpretation (possibly with separate answer). *Code* in the post obviously can't demonstrate mutating a string as OP said they tried the code but presumably code compiles (I would expect different flavor of question for code that does not compile). – Alexei Levenkov May 23 '16 at 23:49
4

A string is immutable. Your extension method creates a new string rather than alter the one passed in. You'd need to write it as:

public static String AppendLine(this String str, string text)
{
    return str + text + Environment.NewLine;
}

And call it like this:

string myStr = "Line 1";
myStr = myStr.AppendLine("Line 2");
Sean
  • 60,939
  • 11
  • 97
  • 136
1

You must return a value from the Extension Method as others have mentioned before. You could also use the new C# expression syntax as follows to return the value.

public static string appendLine(this String str, string text) => str + text + Environment.NewLine;

This does the same thing as a method with a return statement. However, I find it quite elegant.

Ronnie Rahman
  • 316
  • 3
  • 9