How can you change a variable inside a method and also change it outside

前端 未结 2 1034
挽巷
挽巷 2021-01-25 11:54

I have a variable that I want to change inside a function and reflex the new change in the orginal variable . I am trying to change the original variable value to Scott inside t

相关标签:
2条回答
  • 2021-01-25 12:26

    You can do that by passing the string by reference -

    public ActionResult HomePage()
    {
        string name = "John";
        ChangeName(ref name);
        string newName = name ; -- This is now Scott.
    }
    
    public static void ChangeName(ref string myname)
    {
      myname = "Scott";
    }
    

    However, as stated by TheSoftwareJedi in the comments, it is usually best to avoid passing parameters by reference. Instead, you should have your method return the new string, especially considering the fact that strings are immutable, so you can't really change them, you can only change the reference to point to another string.

    So a better method would be something like this:

    public static string GetAnotherName()
    {
      return "Scott";
    }
    

    A little more in depth - there are basically two kinds of types in c# (relevant to this point, at least): There are value types like enums, structs (including all primitive types such as int, bool etc') and there are reference types (basically, everything else).

    Whenever you pass an argument to a method, it gets passed by value, unless you specify the ref (or out) keyword, even if it's a reference type (in that case, the reference gets passed by value). This means that when ever you are assigning a new value to the argument inside the method, you will only see it outside the method if the argument was passed explicitly by reference (using the ref or out keyword).

    The main difference between reference types and value types is that when you change the properties of a reference type inside a method, you will see the new values outside the method as well, however when you change the properties of a value type inside a method, that change will not reflect to the variable outside that method.

    Jon Skeet have written a fairly extensive article about that subject, and he is way better than me in explaining things, so you should probably read it as well.

    0 讨论(0)
  • 2021-01-25 12:43

    To start with, I would recommend you to read about references, values and parameters passing. There is a nice summary on this theme by Jon Skeet — Parameter passing in C# and good explanation of reference concept by Eric Lippert — References are not addresses.

    You should know that by default parameters are passed by value in C#, it means parameter will contain a copy of the reference passed as argument, it means assignments will only change parameter itself and won't be observable at the call site.

    That's why

    myname = "Scott";
    

    Only changes value of the method parameter myname and not the outer name variable.

    At the same time, we are able to pass our variable by reference with use of ref, in or out keywords. Although in and out keywords are adding excess guarantees, which are out of theme discussed, so I'll continue with ref.

    You should change both declaration of your method and call site to use it.

    public static void ChangeName(ref string myname)
    {
        myname = "Scott";
    }
    

    And it should be invoked now as

    ChangeName(ref name);
    

    This time there is no copying, so myname parameter stores the same reference as name variable and, moreover parameter and variable are stored at one location, it means changes to myname inside ChangeName method will be visible to invoking code.

    To continue with, I'd like to point you to a separate, but related theme in regards of your question — Expressions and Statements and to link you to a good article about them written by Scott Wlaschin — Expressions vs statements (there is a bit of F# inside, but that's not critical).

    Generally, there is nothing wrong with approach you've selected, but it's imperative, statement based and a bit too low level. You are forced to deal with references and their values, while what you really want is just to get value "Scott" from your method. This will look more straightforward and obvious, if implemented as an expression.

    public static string GetName() => "Scott";
    

    This way code is declarative and thus more simple (and short), it directly illustrates your goals.

    0 讨论(0)
提交回复
热议问题