1

0假设我创建了一个 ArrayList 并添加了两个字符串:

string item1 = string.Empty;
string item2 = string.Empty;

ArrayList someList = new ArrayList();
someList.Add(item1);
someList.Add(item2);

someFunc(someList);

然后我将 someList 传递给一个方法。该方法对 item1 和 item2 执行一些操作并返回,如下所示:

public void someFunc(ArrayList parameters)
{
    parameters[0] = "Monkeys";
    parameters[1] = "More Monkeys";
}

我希望当 someFunc 返回 item1 等于“Monkeys”并且 item2 等于“More Monkeys”时,因为 someList 分别在索引 0 和 1 中包含对 item1 和 item2 的引用。但是,我看到的是 item1 等于“Monkeys”,而 item2 等于“”。

为什么?如果不通过 ref 单独传递每个项目,我将如何执行此壮举?

4

4 回答 4

3

您的代码根本不会按照您的期望进行。item1您的变量item2不会通过重新分配到列表来修改。您不能将对变量的引用添加到一个ArrayList(或者最好是List<T>现代 .NET 世界中的一个)。您可以简单地添加值本身(可以是对object的引用)。当您覆盖最初存储在列表中的值时,它不会影响先前的变量。

如果您需要更新列表内部以反映外部变量,您可能需要不同的抽象。例如,您将变量设置为类的属性,然后维护该类的列表。然后,您可以通过更改属性来改变类,而不是覆盖列表的内容。Niyoko Yuliawan 的回答中演示了这种技术,所以我不会重新展示它。

提到的另一种技术是将值读回变量中。如果列表具有相同数量的相同顺序的值,这是可行的。但是,我应该注意,如果您将多个值添加到列表中,将它们传递给方法,更改列表中的值,然后将这些值重新读取到变量中,您可能不需要列表,您需要一个类. 如果item1anditem2真的 firstNameand lastName,例如,您不想要ArrayList list(或者,最好List<string> list是 ),那么您真的想要Person person具有string FirstNameandstring LastName属性。

所以如果你有

public void SomeFunc(ArrayList list)
{
     list[0] = "Sam";
     list[1] = "Smith";
}

您可能应该考虑改为定义一个类,然后使用该类。

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";
}
于 2013-03-26T15:25:52.290 回答
2

你不能那样做。但是,您可以这样做:

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";
    }
}
于 2013-03-26T15:26:59.100 回答
1

为了得到你想要的,你必须从你的读回值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];

顺便说一句,没有太多情况下ArrayList是更好的选择List<T>,在这种情况下,List<string>.

于 2013-03-26T15:26:23.133 回答
1

如果不从数组中读取它们,你就无法做到这一点,这里有一个 LinqPad 示例来向你展示输出。如您所见,数组的值已更改,但您的原始变量没有。

    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";
}

使用“真正的”引用类型包装器有效

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";
}
于 2013-03-26T15:31:42.003 回答