0

I have this method:

    namespace MyProject.String.Utils
    {
        public static class String
        {
            public static void formatDecimalSeparator(this string paramString)
            {
                try
                {
                    if (System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator == ",")
                    {
                        paramString = paramString.Replace(".", ",");
                    }
                    else
                    {
                        paramString = paramString.Replace(",", ".");
                    }
                }
                catch
                {
                    throw;
                }
            }
        }
    }

But when I do this:

string myString = "1.23";
myString.formatDecimalSeparator();

The result is not "1,23". The variable is not updated. So I have to change the method to return a string and assign the return value to the same variable.

Why is the variable not updated at the call site? The extension method gets the value of the variable paramString, I can change it in the method, but in the main code the variable is not changed?

CodeCaster
  • 147,647
  • 23
  • 218
  • 272
Álvaro García
  • 18,114
  • 30
  • 102
  • 193
  • 6
    No, you don't have that method. The code doesn't compile, because you can't return anything from a `void` method. What does the actual code that you are using look like? – Guffa Jan 02 '15 at 12:05
  • 1
    _"Why the variable is not updated when the method use as parameter "this", the method get the value of the variable, can change it but in the main code the variable is not changed?"_ - see [C# string reference type?](http://stackoverflow.com/questions/1096449/c-sharp-string-reference-type). – CodeCaster Jan 02 '15 at 12:08
  • Well, I forget to change the returned value by the assignement, but the problem is the same. – Álvaro García Jan 02 '15 at 12:11
  • 1
    @CodeCaster you catch me for second time :P okay you are right ;) – mybirthname Jan 02 '15 at 12:18
  • The answer by @NikhilAgrawal is right, but the real short answer is: "because strings are immutable in c#". The rest are just workarounds to the "problem" :-) – Jcl Jan 02 '15 at 12:30

3 Answers3

6

You need to set return type as string.

public static string formatDecimalSeparator(this string paramString)
{
    try
    {
        if (System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator == ",")
            return paramString.Replace(".", ",");
        else
            return paramString.Replace(",", ".");
     }
     catch
     {
         throw;
     }
 }

and then you have to assign the returned variable:

myString = myString.formatDecimalSeparator();

Strings are immutable. Whenever any change is done in a string, a new instance with changes is returned. Read String is immutable. What exactly is the meaning?.

Tried and Tested

enter image description here

Community
  • 1
  • 1
Nikhil Agrawal
  • 47,018
  • 22
  • 121
  • 208
3

Strings are immutable, so you can't change the string. A reference to the string is passed to the method, but when you try to change the string you are actually changing the reference to point to a new string. The code outside the method still has the reference to the original string.

String methods return a new string, so that is what you would do in your extension method:

namespace MyProject.String.Utils
{
    public static class String
    {
        public static string formatDecimalSeparator(this string paramString)
        {
            if (System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator == ",")
            {
                return paramString.Replace(".", ",");
            }
            else
            {
                return paramString.Replace(",", ".");
            }
        }
    }
}

Usage:

string myString = "1.23";
myString = myString.formatDecimalSeparator();
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • OP's question seems to be about _why_ `paramString` has to be returned: _"Why the variable is not updated when the method use as parameter "this", the method get the value of the variable, can change it but in the main code the variable is not changed?"_. – CodeCaster Jan 02 '15 at 12:10
  • Yes, I forget to change the code to delete the return and use the assignement, but the method has the same behavior. I change the code in the original post. – Álvaro García Jan 02 '15 at 12:13
  • @ÁlvaroGarcía: I have tested the code, and it works. It sounds like you are not using code like the one I showed, but instead assign the string back to the reference passed to the method. – Guffa Jan 02 '15 at 12:16
3

If you want to not return anything, you should pass the string as reference !

            public static void formatDecimalSeparator(ref string paramString)
            {
                try
                {
                    if (System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator == ",")
                    {
                        paramString = paramString.Replace(".", ",");
                    }
                    else
                    {
                        paramString = paramString.Replace(",", ".");
                    }
                }
                catch
                {
                    throw;
                }
            }
mybirthname
  • 17,949
  • 3
  • 31
  • 55