erick manuel Ответов: 2

Необычное поведение при извлечении системы._ _ comobject


В настоящее время я работаю с 3-й сторонней библиотекой dll, которая возвращает систему.__ComObject. Поэтому в обычных обстоятельствах я обычно использую оператор foreach, который может перебирать этот объект, чтобы получить нужные мне данные.

Например
CWMetaData metadata = app.Clients.GetMetaData(userPath);
foreach(var data in metadata)
{
   var getvalue = data;
}


Я получаю систему.__ComObject, когда я перебираю этот объект. Что я считаю странным, потому что эта система.__ComObject имеет другое поведение с оператором for.

Например:
for(int x =0; x< metadata.Count;x++)
{
   var getvalue = metadata[x].Name;
}


В этом заявлении for я могу фактически углубиться в систему.__ComObject, с помощью которого даже обеспечивается intellisense для системы.__ComObject. Я не уверен, в чем разница, но уверен, что оба примера повторяют один и тот же объект.

Мой вопрос заключается в том, почему существует различное поведение между примером один и примером два. Если оба цикла делают одно и то же.

Что я уже пробовал:

Я читал документацию по Маршалингу, но думаю, что она не относится к этому случаю

F-ES Sitecore

- Какой у тебя вопрос?

erick manuel

Мой вопрос заключается в том, почему существует различное поведение между примером один и примером два. Если оба цикла делают одно и то же.

[no name]

Нет, на самом деле они не делают одно и то же. В foreach вы делаете присвоение переменной. Во втором случае вы получаете доступ к свойствам объекта. 2 совершенно разные вещи. Прекращение использования var может сделать это более ясным.

erick manuel

спасибо

[no name]

Я не понимаю, почему вы думаете, что это "необычное поведение". Ваши фрагменты кода делают две разные вещи.

erick manuel

верно, я знаю, но с помощью цикла foreach я получаю comObject, а с другой стороны, с помощью оператора for я углубляюсь в объект.

[no name]

Ладно... и? Это то, что *я* бы ожидать. Как это вообще необычное поведение?

erick manuel

ну только то, что я могу пройти через com_object только с помощью оператора for и получить intellisense. Но я думаю, что это нормально.

2 Ответов

Рейтинг:
17

Midi_Mick

Чтобы лучше понять, вам нужно взглянуть на внутреннюю работу COM. COM-объект, допускающий перечисление в .NET (foreach), фактически возвращает реализацию IEnumVariant, поэтому каждое возвращаемое значение является естественным вариантом, который при маршалировании в .NET, становится объектом типа. Тот факт, что этот объект имеет тип VT_UNKNOWN или VT_DISPATCH, позволяет .NET привести его к ComObject, но фактический COM-объект, на который указывает этот объект, неизвестен. Свойство Item, с другой стороны, обычно возвращает указатель на конкретную реализацию COM-интерфейса, и поэтому тип может быть определен во время компиляции.


Рейтинг:
0

Graeme_Grant

Если вы посмотрите на определение для foreach (в C# Reference)[^]:

The foreach statement repeats a group of embedded statements for each element in an array or an object collection that implements the System.Collections.IEnumerable or System.Collections.Generic.IEnumerable<T> interface. The foreach statement is used to iterate through the collection to get the information that you want, but can not be used to add or remove items from the source collection to avoid unpredictable side effects. If you need to add or remove items from the source collection, use a for loop.
Не имея никакой дополнительной информации о вызываемом объекте и основываясь на приведенной выше информации, я бы пришел к выводу, что System.Collections.IEnumerable или System.Collections.Generic.IEnumerable<T> интерфейс не реализован для C#.