2008-09-17 7 views
5

J'enroulant un C++ natif, qui a les méthodes suivantes:Conversion std :: vector <> :: iterator à l'interface .NET en classe 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) Quel est le » .NET manière "de représenter ce même type d'interface? Une seule méthode renvoyant un tableau <>? Est-ce que le tableau <> generic a des itérateurs, pour que je puisse implémenter BeginLocals() et EndLocals()?

2) Est-ce que Local doit être déclaré valeur struct dans l'encapsuleur .NET?

Je voudrais vraiment représenter la classe enveloppé avec une saveur .NET, mais je suis très nouveau dans le monde géré - et ce type d'information est frustrant de Google pour ...

Répondre

5

itérateurs aren ne sont pas exactement traduisibles à "la façon .net", mais ils sont grossièrement remplacés par IEnumerable T> et IEnumerator T>.

Plutôt que

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

vous verriez (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; 
} 

Ou plus explicitement (sans cacher le IEnumerator derrière le sucre de syntaxe 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; 
} 

Comme vous pouvez voir que foreach ne fait que masquer l'énumérateur .net pour vous.

Donc, vraiment, le ". Net" serait simplement permettre aux gens de créer des éléments locaux pour eux-mêmes. Si vous voulez contrôler l'itération ou rendre la collection un peu plus personnalisée, demandez à votre collection d'implémenter les interfaces IEnumerable T> et/ou ICollection < T>.

A près de la traduction directe de C# serait à peu près ce que vous supposiez:

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

Ensuite, un utilisateur serait en mesure de

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

@Phillip - Merci, votre réponse m'a vraiment commencé dans la bonne direction.

Après avoir vu votre code, et faire un peu plus de lecture dans le livre de Nish C++/CLI en action, je pense à l'aide d'une propriété indexée qui retourne une poignée de suivi const à une instance locale sur le tas managé est probablement le meilleur approche. J'ai fini par mettre en œuvre quelque chose de semblable à ce qui suit:

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

C'est une bonne approche, mais vous voudrez probablement vous assurer également d'exposer une propriété Count au moins :). Une autre note, sans exposer la liste ou implémenter IEnumerable , la classe ne sera pas utilisable par les extensions LINQ dans .net 3.5 –

Questions connexes