28

私はまだ C# に不慣れで、配列に関するさまざまな問題に苦労しています。メタデータ オブジェクト (名前と値のペア) の配列があり、本当に必要な数の "InputProperty" オブジェクトだけを作成する方法を知りたいです。このループでは、要素の数を任意に 20 に設定し、エントリが null になったときに救済しようとしましたが、これを受信する側の Web サービスは、渡された null 要素を好みません。

private Update BuildMetaData(MetaData[] nvPairs)
{
    Update update = new Update();
    InputProperty[] ip = new InputProperty[20];  // how to make this "dynamic"
    int i;
    for (i = 0; i < nvPairs.Length; i++)
    {
        if (nvPairs[i] == null) break;
        ip[i] = new InputProperty();
        ip[i].Name = "udf:" + nvPairs[i].Name;
        ip[i].Val = nvPairs[i].Value;
    }
    update.Items = ip;
    return update;
}

要約すると、上記の入力配列に名前と値のペアが 3 つしかないとしますか? ip という配列に 20 個の要素を割り当てるのではなく、ip が必要なだけの大きさになるようにコーディングするにはどうすればよいでしょうか。更新オブジェクトは別の Web サービスに渡されるため、シリアル化が重要です (つまり、namevaluecollection などを使用できません)。

ps 「コメントを追加」機能を通じて投稿された質問をフォローアップする唯一の方法はありますか?

4

9 に答える 9

30
InputProperty[] ip = new InputProperty[nvPairs.Length]; 

または、次のようにリストを使用できます。

List<InputProperty> list = new List<InputProperty>();
InputProperty ip = new (..);
list.Add(ip);
update.items = list.ToArray();

私が指摘したいもう 1 つのことは、C# では、ループ内の for ループで int 変数の使用を decare できることです。

for(int i = 0; i<nvPairs.Length;i++
{
.
.
}

そして、私が気分に乗っているという理由だけで、このメソッド IMO を実行するためのよりクリーンな方法を次に示します。

private Update BuildMetaData(MetaData[] nvPairs)
{
        Update update = new Update();
        var ip = new List<InputProperty>();

        foreach(var nvPair in nvPairs)
        {
            if (nvPair == null) break;
            var inputProp = new InputProperty
            {
               Name = "udf:" + nvPair.Name,
               Val = nvPair.Value
            };
            ip.Add(inputProp);
        }
        update.Items = ip.ToArray();
        return update;
}
于 2009-03-25T19:30:08.313 に答える
24

List、 、またはその他の動的にサイズ設定されたコレクションを使用せずArrayListに配列に変換する場合 (ちなみに、これは私が推奨する方法です)、配列を可能な限り最大に割り当てる必要があります。入れたアイテムの数を追跡し、それらのアイテムだけを含む新しい配列を作成します。

private Update BuildMetaData(MetaData[] nvPairs)
{
    Update update = new Update();
    InputProperty[] ip = new InputProperty[20];  // how to make this "dynamic"
    int i;
    for (i = 0; i < nvPairs.Length; i++)
    {
        if (nvPairs[i] == null) break;
        ip[i] = new InputProperty(); 
        ip[i].Name = "udf:" + nvPairs[i].Name;
        ip[i].Val = nvPairs[i].Value;
    }
    if (i < nvPairs.Length)
    {
        // Create new, smaller, array to hold the items we processed.
        update.Items = new InputProperty[i];
        Array.Copy(ip, update.Items, i);
    }
    else
    {
        update.Items = ip;
    }
    return update;
}

別の方法は、常に割り当てupdate.Items = ip;てから、必要に応じてサイズを変更することです。

update.Items = ip;
if (i < nvPairs.Length)
{
    Array.Resize(update.Items, i);
}

コードは少なくなりますが、同じ量の作業を行うことになる可能性があります (つまり、新しい配列を作成し、古いアイテムをコピーします)。

于 2009-03-25T19:53:55.260 に答える
8

これを使って:

 Array.Resize(ref myArr, myArr.Length + 5);
于 2012-08-08T12:41:13.850 に答える
5

配列である必要がありますか? ArrayList または C# で使用可能なその他のオブジェクトのいずれかを使用する場合、コンテンツに対するこの制限はありません。Hashtable、IDictionnary、IList などはすべて動的な数の要素を許可します。

于 2009-03-25T19:31:22.117 に答える
2

または、C#3.0を使用System.Linqすると、中間リストをスキップできます。

private Update BuildMetaData(MetaData[] nvPairs)
{
        Update update = new Update();
        var ip = from nv in nvPairs
                 select new InputProperty()
                 {
                     Name = "udf:" + nv.Name,
                     Val = nv.Value
                 };
        update.Items = ip.ToArray();
        return update;
}
于 2009-03-25T19:40:10.847 に答える
2

Array.CreateInstance配列を動的に作成するために使用します。

    private Update BuildMetaData(MetaData[] nvPairs)
    {
        Update update = new Update();
        InputProperty[] ip = Array.CreateInstance(typeof(InputProperty), nvPairs.Count()) as InputProperty[];
        int i;
        for (i = 0; i < nvPairs.Length; i++)
        {
            if (nvPairs[i] == null) break;
            ip[i] = new InputProperty();
            ip[i].Name = "udf:" + nvPairs[i].Name;
            ip[i].Val = nvPairs[i].Value;
        }
        update.Items = ip;
        return update;
    }
于 2012-08-23T20:39:59.227 に答える
2

メソッド内で List を使用し、最後にそれを配列に変換できます。しかし、最大値 20 について話すと、コードはより高速になると思います。

    private Update BuildMetaData(MetaData[] nvPairs)
    {
        Update update = new Update();
        List<InputProperty> ip = new List<InputProperty>();
        for (int i = 0; i < nvPairs.Length; i++)
        {
            if (nvPairs[i] == null) break;
            ip[i] = new InputProperty();
            ip[i].Name = "udf:" + nvPairs[i].Name;
            ip[i].Val = nvPairs[i].Value;
        }
        update.Items = ip.ToArray();
        return update;
    }
于 2009-03-25T19:34:23.933 に答える
0

この方法で動的に配列を作成できます。

 static void Main()
    {
        // Create a string array 2 elements in length:
        int arrayLength = 2;
        Array dynamicArray = Array.CreateInstance(typeof(int), arrayLength);
        dynamicArray.SetValue(234, 0);                              //  → a[0] = 234;
        dynamicArray.SetValue(444, 1);                              //  → a[1] = 444;
        int number = (int)dynamicArray.GetValue(0);                      //  → number = a[0];


        int[] cSharpArray = (int[])dynamicArray;
        int s2 = cSharpArray[0];

    }
于 2012-12-20T20:25:34.220 に答える
0

通常、配列にはそのサイズを初期化するための定数が必要です。nvPairs を 1 回スイープして長さを取得してから、このような長さの変数を使用して「動的に」配列を作成できます。

InputProperty[] ip = (InputProperty[])Array.CreateInstance(typeof(InputProperty), length);

しかし、私はそれをお勧めしません。ただ固執する

List<InputProperty> ip = ...
...
update.Items = ip.ToArray();

解決。パフォーマンスがそれほど低下するわけではなく、見栄えが良くなります。

于 2009-03-25T20:06:07.557 に答える