Преобразование std :: vector <> :: iterator в интерфейс .NET в C ++ / CLI - PullRequest
5 голосов
/ 17 сентября 2008

Я обертываю собственный класс C ++, который имеет следующие методы:

class Native
{
    public:
    class Local
    {
        std::string m_Str;
        int m_Int;
    };

    typedef std::vector<Local> LocalVec;
    typedef LocalVec::iterator LocalIter;

    LocalIter BeginLocals();
    LocalIter EndLocals();

    private:
        LocalVec m_Locals;
};

1) Что такое «способ .NET» для представления такого же интерфейса? Единственный метод, возвращающий массив <>? Есть ли в массиве <> generic итераторы, чтобы я мог реализовать BeginLocals () и EndLocals ()?

2) Должен ли Local быть объявлен как значение struct в оболочке .NET?

Мне бы очень хотелось представить обернутый класс со вкусом .NET, но я очень новичок в управляемом мире - и этот тип информации разочаровывает Google для ...

Ответы [ 2 ]

5 голосов
/ 17 сентября 2008

Итераторы не совсем переводимы в «.net way», но они примерно заменяются IEnumerable и IEnumerator .

Вместо

  vector<int> a_vector;
  vector<int>::iterator a_iterator;
  for(int i= 0; i < 100; i++)
  {
    a_vector.push_back(i);
  }

  int total = 0;
  a_iterator = a_vector.begin();
  while( a_iterator != a_vector.end() ) {
    total += *a_iterator;
    a_iterator++;
  }

вы бы увидели (в c #)

List<int> a_list = new List<int>();
for(int i=0; i < 100; i++)
{
  a_list.Add(i);
}
int total = 0;
foreach( int item in a_list)
{
  total += item;
}

Или более явно (не скрывая IEnumerator за сахаром синтаксиса foreach):

List<int> a_list = new List<int>();
for (int i = 0; i < 100; i++)
{
    a_list.Add(i);
}
int total = 0;
IEnumerator<int> a_enumerator = a_list.GetEnumerator();
while (a_enumerator.MoveNext())
{
    total += a_enumerator.Current;
}

Как видите, foreach просто скрывает перечислитель .net для вас.

Так что, на самом деле, «.net way» - просто позволить людям создавать элементы List для себя. Если вы хотите контролировать итерацию или сделать коллекцию более индивидуальной, попросите вашу коллекцию также реализовать интерфейсы IEnumerable и / или ICollection .

Практически прямой перевод на c # был бы почти таким же, как вы предполагали:

public class Native
{
  public class Local
  { 
     public string m_str;
     public int m_int;
  }

  private List<Local> m_Locals = new List<Local>();

  public List<Local> Locals
  {
    get{ return m_Locals;}
  }
}

Тогда пользователь сможет

foreach( Local item in someNative.Locals)  
{
 ... 
}
0 голосов
/ 17 сентября 2008

@ Филипп - Спасибо, ваш ответ действительно заставил меня начать в правильном направлении.

После просмотра вашего кода и небольшого прочтения в книге Ниша C ++ / CLI в действии я думаю, что использование индексированного свойства, которое возвращает дескриптор отслеживания констант экземпляру Local в управляемой куче, наверное лучший подход. В итоге я реализовал нечто похожее на следующее:

public ref class Managed
{
    public:
    ref class Local
    {
        String^ m_Str;
        int m_Int;
    };

    property const Local^ Locals[int]
    {
        const Local^ get(int Index)
        {
            // error checking here...
            return m_Locals[Index];
        }
    };

    private:
        List<Local^> m_Locals;
};
...