15

I am trying to author an extension method for a string that takes one argument and it appends the argument to the string's value. Here is the behavior I want:

    public static void AddNumber(this string originalValue, string id)
    {
        List<string> ids = originalValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToString();
        ids.Add(id);
        string newValue = string.Join(",", ids);
        originalValue = newValue;
    }

Then I would like to use this as follows:

        string testing = "";
        testing.AddNumber("1"); // value should be 1
        testing.AddNumber("2"); // value should be 1,2
        testing.AddNumber("3"); // value should be 1,2,3

The issue is that I am seeing this:

        string testing = "";
        testing.AddNumber("1"); // value is ""
        testing.AddNumber("2"); // value is ""
        testing.AddNumber("3"); // value is ""

Now I have read the this! issue here on StackOverflow, and I am aware that I am doing a similar thing. I can't replace the entire value of the string, I have to modify the contents of the string that is sent through... I just can't find a way to modify it. I've tried modifying the character array and have had no luck. Any ideas?

Community
  • 1
  • 1
GingerLoaf
  • 1,151
  • 8
  • 6

3 Answers3

23

Strings are immutable.
That's fundamentally impossible.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 1
    Based on all my research and the feedback from everyone else it would seem that it is not possible to create an extension method and have it replace or modify the original value – GingerLoaf Aug 25 '12 at 21:44
  • strange VB.net can do this – Jack Gajanan Apr 24 '16 at 13:54
  • @JackGajanan: No; Strings in VB.Net are also immutable. Or are you talking about `ByRef` parameters? – SLaks Apr 25 '16 at 02:09
  • strings are immutable but "this" of extension is byref _ Public Shared Sub AddNumber(originalValue As String, id As String) End Sub – Jack Gajanan Apr 27 '16 at 06:52
7

To achieve this you would have to pass this string originalValue as ref, but that's not possible. You can do so with a normal method, though:

public static void AddNumber(ref string originalValue, string id)

but it has to be called like this:

AddNumber(ref testing, "1");
Joey
  • 344,408
  • 85
  • 689
  • 683
  • `out` makes more sense than `ref` in this situation. – P.Brian.Mackey Aug 23 '12 at 20:48
  • 3
    @P.Brian.Mackey No, actually, `ref` makes more sense than `out`. He wants to read the string, generate a new string based on that value, and then set the variable to that generated value. Textboox `ref`. – Servy Aug 23 '12 at 20:51
  • Good feedback. I am well aware that using a normal method will work I would just personally like to be able to use this behavior as indicated in the original issue. – GingerLoaf Aug 24 '12 at 23:39
  • You have no way of assigning a reference to a method parameter unless it is declared `ref` (both in the method declaration and on use). For extension methods there is simply no way of stating that, thus it's impossible. – Joey Aug 24 '12 at 23:45
5

You have to use this method like that:

public static string AddNumber(this string originalValue, string id)
    {
        List<string> ids = originalValue.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToString();
        ids.Add(id);
        string newValue = string.Join(",", ids);
        return newValue;
    }

testing = testing.AddNumber("1");

But you can do this with a StringBuilder:

public static void AddNumber(this StringBuilder builder, string id)
{
    var originalValue = builder.ToString();
    if (originalValue.EndsWith(",") || string.IsNullOrEmpty(originalValue))
         builder.Append(id);
    else
         builder.Append("," + id);
}

var testing = new StringBuilder();
testing.AddNumber("1");
testing.AddNumber("2");
testing.AddNumber("3");

I also changed the algorithm. It doesn't look so efficient.

Amiram Korach
  • 13,056
  • 3
  • 28
  • 30