Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialize List<T> with array in CLR C++?

I was wondering why this code does not work in C++/CLI but damn easy in C#?

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

error C2664: 'System::Collections::Generic::List::List(System::Collections::Generic::IEnumerable ^)' : cannot convert parameter 1 from 'cli::array ^' to 'System::Collections::Generic::IEnumerable ^'

Here is what I come up with. Did perfectly well. :)

List<Process^>^ processList = gcnew List<Process^>(
  safe_cast<System::Collections::Generic::IEnumerable<Process^>^>
    (Process::GetProcessesByName(this->processName)));
like image 840
Jimson James Avatar asked Aug 28 '12 04:08

Jimson James


1 Answers

You need to use safe_cast. According to the MSDN documentation on System::Array,

Important

Starting with the .NET Framework 2.0, the Array class implements the System.Collections.Generic::IList<T>, System.Collections.Generic::ICollection<T>, and System.Collections.Generic::IEnumerable<T> generic interfaces. The implementations are provided to arrays at run time, and therefore are not visible to the documentation build tools. As a result, the generic interfaces do not appear in the declaration syntax for the Array class, and there are no reference topics for interface members that are accessible only by casting an array to the generic interface type (explicit interface implementations). The key thing to be aware of when you cast an array to one of these interfaces is that members which add, insert, or remove elements throw NotSupportedException.

As you can see, the cast must be done explicitly in C++ at runtime, e.g.

List<Process^>^ processList = gcnew List<Process^>(
    safe_cast<IEnumerable<T> ^>(
        Process::GetProcessesByName(this->processName)));
like image 88
obataku Avatar answered Sep 25 '22 10:09

obataku