0

I want to set a value for array item variable:

string string1;
string string2;
string[] myArray = { string1, string2 };

public Test(){
  for(int i=0; i < myArray.Length; i++){
    myArray[i] = "hello!";
  }
}

If I use myArray[i] = "Hello" method, then it sets to myArray value not string1 and string2 value.

wonyh_
  • 132
  • 1
  • 9
  • 3
    Ok. So what specifically is the problem? – ADyson Apr 03 '21 at 07:25
  • Can you explain what you are trying to do? `string1 = "hello";`? – knittl Apr 03 '21 at 07:26
  • @knittl yes, i want to change string1 and string2 value – wonyh_ Apr 03 '21 at 07:29
  • If you have an array of values why do you need the individual ones as well? That just seems like unnecessary duplication. – ADyson Apr 03 '21 at 07:37
  • @ADyson because i want to change string1 and string2 value using "for" method – wonyh_ Apr 03 '21 at 07:40
  • 3
    Yes, but my point was, why do you need string1 and string2 at all? Why not just simply store the data in the array, and forget about the individual variables? – ADyson Apr 03 '21 at 07:44
  • I think his question is about value types and reference types. At least, that is the 'phenomenon' the OP is trying to understand.. – Stefan Apr 03 '21 at 08:14

4 Answers4

1

An array in C# contains primitive values (integers, doubles, booleans, …) or references (references to class or struct instances). When you update one item of the array, you are only changing the "value" in the array. You are not updating thte object being pointed to. In other words: you are only swapping the reference to point to a different object, the object is never changed.

To achieve this, you need to insert another level of inderection (think pointer to pointer in good ol' C).

One option to achieve this would be to introduce a wrapper type to hold your value and allow to update it:

class Reference<T> {
  T Value { get; set; }
  public Reference(T value) {
    this.Value = value;
  }
}

Reference<string> string1;
Reference<string> string2;
Reference<string>[] myArray = { string1, string2 };

public Test() {
  for(int i = 0; i < myArray.Length; i++) {
    myArray[i].Value = "hello!";
  }
}
knittl
  • 246,190
  • 53
  • 318
  • 364
0

I am not exactly sure what you're asking but I think your confusion is about reference and value types.

If you want to write to string1 and string2 using myArray you have to know a thing or two about value and reference types in C#.

For your current usage you can consider string a value type. With this I mean: that if you assign a string to another string (string stringX = a_previous_declared_String) it creates a copy. Changing the copy will not change the original. Storing your string in MyArray also creates a copy.

(Please note that in fact string is a reference type which behaves like a value type when doing assignment (stringX = stringY) operations. If you want to know more, you can e.g. start here. For the purpose of explaining the general difference between value types and reference types, using your example, I simplify an call string a value type here).

If you want to change the original, you have to store a reference to your string in myArray. For this, in C#, you can create a reference type variable which holds your value type. This can be a class which holds your string as a field. Then, you store a reference to your class in MyArray. If you then change the string via MyArray, your original string1 and string2 wil also get modified.

I created the simplest version of this to help you understand. See @knittl his answer for a more general implementation that would work for other value types (like int and float) as well.

My example (which I tested and runs as C# console application):

using System;

namespace TestProgram
{
    public class RefTypeString
    {
        public string MyString;
        public RefTypeString(string myString)
        {
            MyString = myString;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            RefTypeString string1 = new RefTypeString(null);
            RefTypeString string2 = new RefTypeString("initial value");
            RefTypeString[] myArray = { string1, string2 };

            for (int i = 0; i < myArray.Length; i++)
            {
                if (i == 0)
                {
                    myArray[i].MyString = "hello!"; //set value for string1 and string2 not an array
                }
            }

            Console.WriteLine("MyArray[0] / string1");
            Console.WriteLine(myArray[0].MyString);

            Console.WriteLine("MyArray[1] / string1");
            Console.WriteLine(myArray[1].MyString);

            Console.WriteLine("string1");
            Console.WriteLine(string1.MyString);

            Console.WriteLine("string2");
            Console.WriteLine(string2.MyString);
        }
    }
}

Console output:

MyArray[0] / string1
hello!
MyArray[1] / string1
initial value
string1
hello!
string2
initial value
Stefan
  • 919
  • 2
  • 13
  • 24
  • Am I the only one who completely does not understand this answer?) – OlegI Apr 03 '21 at 07:38
  • @Olegl, I hope so ;) – Stefan Apr 03 '21 at 08:52
  • *(Although not 100% accurate), for your current usage you can consider string a value type.* is misleading. – tymtam Apr 03 '21 at 09:07
  • @tymtam, why? As I explain in the answer, when he assigns a string, it will create a copy. Nothing misleading here, and I make a notion that here is more behind it so the OP can search an read all about value types, reference types and how strings fit in there. – Stefan Apr 03 '21 at 09:14
  • @tymtam, Ok, now there can be no doubt about the fact that `string` is somewhat a special case. – Stefan Apr 03 '21 at 10:30
0

you need to initialize the empty string for "string1" & "string2". then it will take the value in it.

        string string1="";
        string string2="";
        string[] myArray = { string1, string2 };

        for (int i = 0; i < myArray.Length; i++)
        {
            myArray[i] = "hello!";
        }
  • 2
    This will not work. After the loop, the reference `string1` will still point to the string value `""`. Only ther reference inside the array is updated to point to a different string value. – knittl Apr 03 '21 at 09:20
0

You cannot change variables string1 and string2 by manipulating the array.

I hope the following snippet makes it clearer what happens. The important part is that when the array is created it contains references to the objects that the variables point to, not to the variables themselves. a[i] = changes what the array element points to, not what variable it was created from.

// Int is a value type
int i1 = 1;
int[] ai = { i1 }; // the array contains the actual number '1', 
                   // each element of the array is the size of int  

ai[0] = 7; // This swaps number 1 to 7 *inside* the array

// C is a class which is a reference type
C c = new C { Property = 1 };
C[] a2 = { c }; // the array contains the reference to 'c' 

// Now both c and a2[0] point to the same object
// Importantly, c doesn't control the array 
//          and the array doesn't control variable c
// They just point to the same object

a2[0].Property = 2; // This changes Property of the object a2 points, 
                    // which is the same object c points to

// Please note that c.Property = 3; would not change the array, 
// it would change the object that a[0] also points to. 

// However, we can also change what object a[0] points too;
a2[0] = new C { Property = 4 }; // This makes a[0] point to a new object 

// In C# string is a reference type 
string string1 = "Hello1";
string[] myArray = { string1 };

myArray[0] = "hello!"; // This makes myArray[0] point to another object and that object is a new string "hello!"
tymtam
  • 31,798
  • 8
  • 86
  • 126