C# доступ к объектам управления в ManagementObjectCollection

Я пытаюсь получить доступ к ManagementObjects в ManagementObjectCollection без использования оператора foreach, возможно, я что-то упускаю, но я не могу понять, как это сделать, мне нужно сделать что-то вроде следующего:

ManagementObjectSearcher query = new ManagementObjectSearcher(
     "select Name, CurrentClockSpeed from Win32_Processor");

ManagementObjectCollection queryCollection = query.Get();

ManagementObject mo = queryCollection[0];

4 ответов


ManagementObjectCollection реализует IEnumerable или ICollection, поэтому либо вы должны повторить его через IEnumerable (т. е. foreach), либо скопировать в массив через ICollection.

однако, поскольку он поддерживает IEnumerable, вы можете использовать Linq:

ManagementObject mo = queryCollection.OfType<ManagementObject>().FirstOrDefault()

OfType<ManagementObject> требуется, потому что ManagementObjectCollection поддерживает IEnumerable, но не IEnumerable из T.


вы не можете напрямую вызвать linq из ManagementObjectCollection (или целочисленного индексатора). Сначала вы должны бросить его в IEnumerable:

var queryCollection = from ManagementObject x in query.Get()
                      select x;

var manObj = queryCollection.FirstOrDefault();

ManagementObjectCollection не реализует индексаторы, Но да, вы можете использовать функцию расширения FirstOrDefault, если вы используете linq, но выродки, которые используют .net 3 или более ранние версии (например, я все еще работаю над 1.1), могут использовать следующий код, это стандартный способ получения первого элемента из любой коллекции, реализованной IEnumerable интерфейс.

//TODO: Do the Null and Count Check before following lines
IEnumerator enumerator = collection.GetEnumerator();
enumerator.MoveNext();
ManagementObject mo = (ManagementObject)enumerator.Current;

ниже приведены два разных способа извлечения ManagementObject из любого индекса

private ManagementObject GetItem(ManagementObjectCollection collection, int index)
{
            //TODO: do null handling 

            IEnumerator enumerator = collection.GetEnumerator();

            int currentIndex = 0;
            while (enumerator.MoveNext())
            {
                if (currentIndex == index)
                {
                    return enumerator.Current as ManagementObject;
                }

                currentIndex++;
            }

            throw new ArgumentOutOfRangeException("Index out of range");
 }

или

private ManagementObject GetItem(ManagementObjectCollection collection, int index)
{
            //TODO: do null handling 

            int currentIndex = 0;
            foreach (ManagementObject mo in collection)
            {
                if (currentIndex == index)
                {
                    return mo;
                }

                currentIndex++;
            }

            throw new ArgumentOutOfRangeException("Index out of range");
 }

вы, вероятно, пропустили бросок:

ManagementObject mo = (ManagementObject)queryCollection[0];

...поскольку я не думаю, что ManagementObjectCollection является общим (и как таковой не имеет типизированного индексатора.)