Reputation: 104
0Suppose I have created an ArrayList and added two strings as such:
string item1 = string.Empty;
string item2 = string.Empty;
ArrayList someList = new ArrayList();
someList.Add(item1);
someList.Add(item2);
someFunc(someList);
Then I take someList and pass it into a method. That method performs some manipulation on item1 and item2 and returns, as such:
public void someFunc(ArrayList parameters)
{
parameters[0] = "Monkeys";
parameters[1] = "More Monkeys";
}
I would expect that when someFunc returns that item1 equals "Monkeys" and item2 equals "More Monkeys" as someList contains references to item1 and item2 in indices 0 and 1 respectively. However, what I am seeing is that item1 equals "Monkeys" and item2 equals "".
Why? And how would I perform this feat without passing in each item individually by ref?
Upvotes: 1
Views: 3053
Reputation: 7672
You can't do that. However, you can do it like this:
class Program
{
class SomeClass
{
public string Content { get; set; }
}
static void Main(string[] args)
{
SomeClass a, b;
a = new SomeClass { Content = "" };
b = new SomeClass { Content = "" };
ArrayList al = new ArrayList();
al.Add(a);
al.Add(b);
SomeFunction(al);
Console.WriteLine(a.Content);
Console.WriteLine(b.Content);
Console.ReadLine();
}
public static void SomeFunction(ArrayList param)
{
((SomeClass)param[0]).Content = "aa";
((SomeClass)param[1]).Content = "bb";
}
}
Upvotes: 2
Reputation: 126864
Your code will simply not do what you expect. Your variables item1
and item2
will not be modified by reassigning to the list. You cannot add a reference to a variable to an ArrayList
(or preferably a List<T>
in the modern .NET world). You can simply add the value itself (which could be a reference to an object). When you overwrite the value that was originally stored in the list, it does not impact the previous variable.
If you need updates inside the list to reflect on outer variables, you may need a different abstraction. You make your variables properties of a class, for example, and then maintain a list of that class. And instead of overwriting the contents of your list, you could then mutate the class by changing the property. This technique is demonstrated in Niyoko Yuliawan's answer, so I will not redisplay it.
Another technique mentioned is to read the values back into your variables. If the list has the same number of values in the same order, this is doable. However, I should note that if you are adding multiple values to a list, passing them into a method, changing the values in the list, and then rereading those values into your variables, you probably did not need a list, you needed a class. If item1
and item2
are really firstName
and lastName
, for example, you don't want ArrayList list
(or, again, preferably List<string> list
), you really want Person person
that has string FirstName
and string LastName
properties.
So if you had
public void SomeFunc(ArrayList list)
{
list[0] = "Sam";
list[1] = "Smith";
}
You probably should consider instead defining a class and then working with that class.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
// elsewhere in your code...
public void SomeFunc(Person person)
{
person.FirstName = "Sam";
person.LastName = "Smith";
}
Upvotes: 3
Reputation: 178
You cant do this without reading them back from the Array, here is a LinqPad example to show you the output. As you can see the value of the array has changed but your original variables haven`t.
void Main()
{
string item1 = "test1";
string item2 = "test2";
ArrayList someList = new ArrayList();
someList.Add(item1);
someList.Add(item2);
item1.Dump();
item2.Dump();
someFunc(someList);
item1.Dump();
item2.Dump();
someList.Dump();
}
public void someFunc(ArrayList parameters)
{
parameters[0] = "Monkeys";
parameters[1] = "More Monkeys";
}
using a "true" reference type wrapper works
public class StringWrapper
{
public string value;
}
void Main()
{
StringWrapper item1 = new StringWrapper() {value = "test1" };
StringWrapper item2 = new StringWrapper() {value = "test2" };
List<StringWrapper> someList = new List<StringWrapper>();
someList.Add(item1);
someList.Add(item2);
item1.Dump();
item2.Dump();
someFunc(someList);
item1.Dump();
item2.Dump();
someList.Dump();
}
public void someFunc(List<StringWrapper> parameters)
{
parameters[0].value = "Monkeys";
parameters[1].value = "More Monkeys";
}
Upvotes: 1
Reputation: 45135
To get what you wanted, you'd have to read the values back from your ArrayList
:
string item1 = string.Empty;
string item2 = string.Empty;
ArrayList someList = new ArrayList();
someList.Add(item1);
someList.Add(item2);
someFunc(someList);
item1 = (string)someList[0];
item2 = (string)someList[1];
BTW, there aren't too many cases where ArrayList
is a better choice that List<T>
, in this case, List<string>
.
Upvotes: 1