0

Why my code Array value always contain "0" ?

        static void Main(string[] args)
        {
            string Input = Console.ReadLine();
            char[] Number = new char[3];
            Util.SetNumber(Input,Number);
            foreach (char digit in Number)
            {
                Console.WriteLine(digit);
            }
            Console.ReadKey();            
        }

This is the Class :

    class Util
    {
        public static void SetNumber(string Input,char[] Number)
        {            
            Number = Input.ToCharArray();                   
        }

    }

But if the "foreach" part i put it in Util.cs, it write the values..

Thank you before,

3 Answers3

7

This is because you're not filling the array. In the method you're replacing the value (a reference to an array) held by the local variable Number with a completely new array. Such a change obviously cannot remain outside that method.

You could use Array.Copy or pass Number as ref:

Array.Copy(Input.ToCharArray(), Number, 3);

or

public static void SetNumber(string Input, ref char[] Number)
{
    Number = Input.ToCharArray();
}

and then invoke it as follows:

Util.SetNumber(Input, ref Number);

Another (probably better) option here would be to use out instead of ref as out doesn't require you to initialise the variable you pass as parameter, so you don't need to do char [] Number = new char[3]; and can just use char [] Number; and pass it without further initialisation. That being said, when you use out you have to assign it a value in the method, so depending on how complex it's going to be that may or may not be feasible.

Here's a nice writeup on parameter passing in C# by Jon Skeet (You may have seen one or two answers by him on this site).

Minor side note: Maybe it's a deliberate decision, but your variable names do not adhere to the C# code guidelines which state that fields, parameters to methods and local variables have to use camelCase naming. PascalCase is reserved for types, methods and properties.

Community
  • 1
  • 1
Joey
  • 344,408
  • 85
  • 689
  • 683
  • Logical, but is not C# arrays are passed by reference by default? As I remember, this is inherited from C++ – Ken D Jun 03 '13 at 06:13
  • 1
    It's a reference which is passed by value. You can mutate that value all you like, but it won't persist outside the method. Note that in C++ you'd have the same problem, if you just pass a `char *` – changing that pointer will not change anything outside that method. – Joey Jun 03 '13 at 06:15
  • 1
    Feel free to refer to http://pobox.com/~skeet/parameters.html if you think it would help :) – Jon Skeet Jun 03 '13 at 06:18
  • I understand that, in C#/C++, arrays references (pointer to the array on the heap) are passed by value, this means, we can change (and persist our change) on the content of the value, AND this is what the OP trying to do! Check [this](http://stackoverflow.com/a/967413/502436) – Ken D Jun 03 '13 at 06:21
  • 1
    I think [this](http://www.yoda.arachsys.com/csharp/parameters.html) is a mirror to what @JonSkeet tried to post. – Ken D Jun 03 '13 at 06:22
  • 1
    LordCover: Yes, this is why I suggested using `Array.Copy` which operates on the *contents* of the array. The second option with `ref` was suggested if they thought they'd have to use assignment for some reason. – Joey Jun 03 '13 at 06:22
  • @Joey: Darn - meant to be http://pobox.com/~skeet/csharp/parameters.html - I forgot the csharp bit. Doh. – Jon Skeet Jun 03 '13 at 06:23
  • I see, because that OP tried `Number = Input.ToCharArray();`, this is considered changing the reference, which will not work now because the reference is passed by value, so the change will be lost. but if the OP used a for loop and assigned to `Number[counter]`, his method will work without the need to pass using `ref`, right? – Ken D Jun 03 '13 at 06:25
  • LordCover, apart from the compiler complaining that `counter` doesn't exist, yes. Inside the method you get a copy of the reference to the array. When you assing something to that copy the array doesn't notice or care, but if you access the array and modify its contents (which works through the copy as well as through the original reference) those changes work as expected. If you use `ref` the parameter to `SetNumber` becomes an *alias* for the variable in the calling method. There's no copying going on, you're accessing the exact same thing (and can mutate the reference through assignment). – Joey Jun 03 '13 at 06:28
  • Of course, `counter` is declared but omitted for brevity. Now we are on the same page :), I will read @JonSkeet article for deeper understanding. – Ken D Jun 03 '13 at 06:31
  • @ All : mmmm,,, i become confuse now... @_@ where should i start.. i really want to understand what u all talking.. – user2168717 Jun 03 '13 at 06:31
  • @user2168717 Go back one level and study passing variables by value/reference to get a solid background, then escalate that understanding to be applied on arrays (Same applies for C++ pointers). What you should focus on here is after passing array by value/ref, what we can change of array_content/array_pointer. P.S: An introduction to the stack vs. the heap would help too. – Ken D Jun 03 '13 at 06:35
3

Better implementation would be (I think)

class Util
{
    public static char[] SetNumber(string Input)
    {
        return Input.ToCharArray();
    }

}

and

    string Input = Console.ReadLine();
    char[] Number = Util.SetNumber(Input);

    foreach (char digit in Number)
    {
        Console.WriteLine(digit);
    }
    Console.ReadKey(); 

also in the original code the assignment char[] Number = new char[3]; can be remove since you create new one in your Util class

Mzf
  • 5,210
  • 2
  • 24
  • 37
  • Indeed, functions work much nicer for that purpose. Although in that case one can probably just forego that method and use `ToCharArray` directly. Also the method name doesn't line up with what it does now anymore. – Joey Jun 03 '13 at 06:17
  • @Јοеу you are right. about the method name but this was the original one. – Mzf Jun 03 '13 at 06:19
0

You can get rid of the Util class altogether

string input = Console.ReadLine();

foreach (var digit in input.ToCharArray())
{
        Console.WriteLine(digit);    
}

Console.ReadKey(); 
NeddySpaghetti
  • 13,187
  • 5
  • 32
  • 61