Convertendo std :: vector <> :: iterador para .NET interface no C ++ / CLI
-
01-07-2019 - |
Pergunta
Estou embrulhar um nativo C ++ classe, que tem os seguintes métodos:
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) Qual é o "caminho .NET" de representar esse mesmo tipo de interface? Um único método retornando um array <>? Será que o array <> genérico tem iteradores, de modo que eu poderia implementar BeginLocals () e EndLocals ()?
2) deve local ser declarado como valor struct no .NET invólucro?
Eu realmente gostaria de representar a classe envolvida com um sabor .NET, mas eu sou muito novo para o mundo conseguiu - e este tipo de informação é frustrante para google para ...
Solução
Iterators não são exatamente traduzíveis para "o caminho .net", mas eles são mais ou menos substituído por IEnumerable
Ao invés 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++;
}
você veria (em 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, mais explicitamente (sem esconder o IEnumerator atrás do açúcar sintaxe 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 você pode ver, foreach apenas oculta o .net recenseador para você.
Então, realmente, o "caminho .net" seria simplesmente permitir que as pessoas a criar uma lista
A próxima tradução direta para c # seria muito bonito o que você assumiu:
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;}
}
}
Em seguida, um usuário seria capaz de
foreach( Local item in someNative.Locals)
{
...
}
Outras dicas
@Phillip - Obrigado, sua resposta realmente me iniciou na direção certa.
Depois de ver seu código, e fazer um pouco mais de ler no livro de Nish C ++ / CLI em Ação , acho que usando uma propriedade indexada que retorna um manipulador de rastreamento const para uma instância local no heap gerenciado é provavelmente a melhor abordagem. Acabei implementar algo semelhante ao seguinte:
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;
};