1

0 ArrayListを作成し、次のように2つの文字列を追加したとします。

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が「MoreMonkeys」に等しいことを返す場合、someListにはそれぞれインデックス0と1のitem1とitem2への参照が含まれていると思います。しかし、私が見ているのは、item1が "Monkeys"に等しく、item2が""に等しいということです。

なんで?そして、refによって各アイテムを個別に渡すことなく、この偉業をどのように実行しますか?

4

4 に答える 4

3

あなたのコードは単にあなたが期待することをしません。変数は、リストに再割り当てしても変更さitem1item2ません。変数への参照をArrayList(またはList<T>現代の.NETの世界ではできれば)に追加することはできません。値自体を追加するだけです(オブジェクトへの参照である可能性があります)。リストに最初に保存された値を上書きしても、前の変数には影響しません。

外部変数を反映するためにリスト内の更新が必要な場合は、別の抽象化が必要になる場合があります。たとえば、変数をクラスのプロパティにしてから、そのクラスのリストを維持します。また、リストの内容を上書きする代わりに、プロパティを変更してクラスを変更することもできます。このテクニックは、ニヨコ・ユリアワンの回答に示されているので、再表示しません。

言及されている別の手法は、値を変数に読み戻すことです。リストに同じ順序で同じ数の値がある場合、これは実行可能です。ただし、リストに複数の値を追加し、それらをメソッドに渡し、リスト内の値を変更してから、それらの値を変数に再読み込みする場合は、おそらくリストは必要なく、クラスが必要であることに注意してください。 。item1item2本当に firstNameである場合lastName、たとえば、必要がない場合ArrayList list(または、繰り返しますが、できればList<string> list)、プロパティPerson personを持っている必要がstring FirstNameありstring 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 に答える