Инициализировать список <T> с массивом в CLR С++?

Мне было интересно, почему этот код не работает в С++/CLI, но прост в С#?

List<Process^>^ processList = gcnew List<Process^>(
  Process::GetProcessesByName(this->processName)););

ошибка C2664: 'System:: Collections:: Generic:: List:: List (System:: Collections:: Generic:: IEnumerable ^)': не может преобразовать параметр 1 из 'cli:: array ^' в 'System:: Коллекции:: Generic:: IEnumerable ^ '

Вот что я придумал. Отлично.:)

List<Process^>^ processList = gcnew List<Process^>(
  safe_cast<System::Collections::Generic::IEnumerable<Process^>^>
    (Process::GetProcessesByName(this->processName)));

Ответ 1

Вам нужно использовать safe_cast. Согласно документации MSDN на System::Array,

Внимание!

Начиная с .NET Framework 2.0, класс Array реализует общие интерфейсы System.Collections.Generic::IList<T>, System.Collections.Generic::ICollection<T> и System.Collections.Generic::IEnumerable<T>. Реализации предоставляются массивам во время выполнения и поэтому не видны инструментам сборки документации. В результате общие интерфейсы не отображаются в синтаксисе объявления для класса Array, и для членов интерфейса нет ссылочных тем, которые доступны только путем литья массива в тип общего интерфейса (явный реализация интерфейса). Ключевое значение, которое нужно учитывать при создании массива на одном из этих интерфейсов, - это элементы, которые добавляют, вставляют или удаляют элементы throw NotSupportedException.

Как вы можете видеть, актер должен выполняться явно в С++ во время выполнения, например.

List<Process^>^ processList = gcnew List<Process^>(
    safe_cast<IEnumerable<T> ^>(
        Process::GetProcessesByName(this->processName)));