2008-09-17 12 views
5

estoy envolviendo una clase nativa de C++, que tiene los siguientes métodos:conversión de std :: vector <> :: iterador a la interfaz de .NET en C++/CLI

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) ¿Cuál es el" .NET manera "de representar este mismo tipo de interfaz? ¿Un único método devuelve una matriz <>? ¿El array <> genérico tiene iteradores, por lo que podría implementar BeginLocals() y EndLocals()?

2) local debe ser declarada como una estructura valor en el envoltorio NET?

Realmente me gustaría representar a la clase envuelto con un sabor .NET, pero soy muy nuevo en el mundo logrado - y este tipo de información es frustrante a Google por ...

Respuesta

5

Iteradores aren no se puede traducir exactamente a "la vía .net", pero se sustituyen aproximadamente por IEnumerable < T> e IEnumerator < T>.

En lugar de

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++; 
    } 

que se vería (en 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; 
} 

O más explícitamente (sin ocultar el IEnumerator detrás del azúcar sintaxis 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; 
} 

Como usted puede ver, foreach solo oculta el enumerador .net por usted.

Así que, en realidad, la "vía de acceso .net" sería simplemente permitir a las personas crear elementos List < Local> por sí mismos. Si desea controlar la iteración o hacer que la colección sea un poco más personalizada, haga que su colección implemente las interfaces IEnumerable < T> y/o ICollection < T>.

Una traducción cerca directo a C# sería más o menos lo que asumió:

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;} 
    } 
} 

A continuación, un usuario sería capaz de

foreach(Local item in someNative.Locals) 
{ 
... 
} 
0

@Phillip - Gracias, su respuesta realmente me inició en la dirección correcta.

Después de ver su código, y haciendo un poco más lectura en el libro de Nish C++/CLI en Acción, creo que el uso de una propiedad indexada que devuelve un identificador de seguimiento const a una instancia local en el montón administrado es probablemente el mejor enfoque. Terminé implementando algo similar a lo siguiente:

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; 
}; 
+0

Ese es un buen enfoque, pero probablemente también querrás asegurarte de exponer al menos una propiedad Count :). Otra nota, sin exponer la lista o implementar IEnumerable < T >, la clase no será utilizable por las extensiones de LINQ en .NET 3.5 –

Cuestiones relacionadas