2

私は持っていobjectます。

このオブジェクトはキャストしてItems Containerいます(どのアイテムかはわかりませんが、確認できます)。

しかし、そこに含まれるアイテムの数を見つけるのに役立つコードはありますか?

つまり

 object[] arrObj = new object[2] {1, 2};
 object o = (object)arrObj;

この場合arrObjは配列なので、次のことを確認できます。

((Array)o).Length// 2

しかし、他に2つある場合はどうなりますか?

 ArrayList al = new ArrayList(2);
           al.Add(1);
           al.Add(2);
 object o = (object)al ;

 List<object> lst= new List<object>(2);
 object o = (object)lst;

oこのキャストされたオブジェクト(このサンプル)に含まれるアイテムの数を見つけるのに役立つ一般的なコードはありますか?

もちろん確認はできますif (o is ...) { }が、もっと一般的なコードを探しています。

4

3 に答える 3

4

すべてのコンテナが実装するインターフェースにキャストできますIEnumerable。ただし、パフォーマンスを向上させるには、最初に次のことを試してみることをお勧めしIEnumerable<T>ます。

var count = -1;
var enumerable = lst as IEnumerable<object>;
if(enumerable != null)
    count = enumerable.Count();
else
{
    var nonGenericEnumerable = lst as IEnumerable;
    count = nonGenericEnumerable.Cast<object>().Count();
}

Count()使用可能にするには、.csファイルに追加する必要がありますusing System.Linq;

このコードには1つの大きな利点があることに注意してください。コレクションが参照型のICollection<T>類似List<T>または強い型の配列を実装する場合、このコードはO(1)で実行されます[O(1)での実行の具体的な実装を想定ICollection<T>.Count]。値型の強い型の配列のように、そうでない場合にのみ、ArrayListこのコードはO(n)で実行され、さらに、値型の配列の場合は項目がボックス化されます。

于 2013-02-01T14:10:23.003 に答える
3

linqを使用できます。

var count = ((IEnumerable)o).Cast<object>().Count();

タイプoに実装IEnumerableがありusing System.Linq、ファイルの先頭にあることを確認してください。

于 2013-02-01T14:08:26.933 に答える
2

それが実装できる最も基本的なインターフェースはIEnumerableです。残念ながらEnumerable.Count、LINQからでもが実装されてIEnumerable<T>いますが、独自の記述を簡単に行うことができます。

public static int Count(IEnumerable sequence)
{
    // Shortcut for any ICollection implementation
    var collection = sequence as ICollection;
    if (collection != null)
    {
        return collection.Count;
    }

    var iterator = sequence.GetEnumerator();
    try
    {
        int count = 0;
        while (iterator.MoveNext())
        {
            count++;
        }
        return count;
    }
    finally
    {
        IDisposable disposable = iterator as IDisposable;
        if (disposable != null)
        {
            disposable.Dispose();
        }
    }
}

これは基本的に次と同等であることに注意してください。

int count = 0;
foreach (object item in sequence)
{
    count++;
}

...ただし、を使用することはないため、たとえばコンテナが実際にあるCurrent場合は、ボクシングを行う必要はありません。int[]

それを呼び出す:

var sequence = container as IEnumerable;
if (sequence != null) 
{
    int count = Count(sequence);
    // Use the count
}

ボクシングを回避することは、実際には少し微妙な最適化であることに注意してください。それが実際に重要になる可能性は低いです。しかし、この方法だけで一度それを行うことができ、それからどこでもそれを利用することができます。

于 2013-02-01T14:10:29.867 に答える