I am wrapping a native C++ class, which has the following methods:
我正在包装一个本机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) What is the ".NET way" of representing this same kind of interface? A single method returning an array<>? Does the array<> generic have iterators, so that I could implement BeginLocals() and EndLocals()?
1)什么是“?”代表这种接口的网络方式?一个返回数组<>的方法?数组<>泛型是否有迭代器,以便我可以实现beginlocal()和endlocal()?
2) Should Local be declared as a value struct in the .NET wrapper?
2)是否应该将Local声明为.NET包装器中的值结构体?
I'd really like to represent the wrapped class with a .NET flavor, but I'm very new to the managed world - and this type of information is frustrating to google for...
我真的很想用。net风格来表示封装的类,但我对托管世界非常陌生——这种类型的信息让谷歌很沮丧,因为……
2 个解决方案
#1
5
Iterators aren't exactly translatable to "the .net way", but they are roughly replaced by IEnumerable < T > and IEnumerator < T >.
迭代器不能准确地翻译成“。net方式”,但它们大致上被IEnumerable < T >和IEnumerator < T >所取代。
Rather than
而不是
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++;
}
you would see (in c#)
你会看到(在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;
}
Or more explicitly (without hiding the IEnumerator behind the foreach syntax sugar):
或更明确地(不隐藏在foreach语法sugar后面的IEnumerator):
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;
}
As you can see, foreach just hides the .net enumerator for you.
正如您所看到的,foreach都为您隐藏了。net枚举器。
So really, the ".net way" would be to simply allow people to create List< Local > items for themselves. If you do want to control iteration or make the collection a bit more custom, have your collection implement the IEnumerable< T > and/or ICollection< T > interfaces as well.
所以,真正的“。net方法”是让人们为自己创建List< Local >项。如果您确实想控制迭代或使集合更自定义一些,那么让您的集合实现IEnumerable< T >和/或ICollection< T >接口。
A near direct translation to c# would be pretty much what you assumed:
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;}
}
}
Then a user would be able to
然后用户就可以
foreach( Local item in someNative.Locals)
{
...
}
#2
0
@Phillip - Thanks, your answer really got me started in the right direction.
@Phillip -谢谢,你的回答让我开始正确的方向。
After seeing your code, and doing a little more reading in Nish's book C++/CLI in Action, I think using an indexed property that returns a const tracking handle to a Local instance on the managed heap is probably the best approach. I ended up implementing something similar to the following:
在看到您的代码并在Nish的书c++ /CLI中做了一些阅读之后,我认为使用一个索引属性来返回托管堆上的本地实例的const跟踪句柄可能是最好的方法。我最终实现了类似如下的东西:
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;
};
#1
5
Iterators aren't exactly translatable to "the .net way", but they are roughly replaced by IEnumerable < T > and IEnumerator < T >.
迭代器不能准确地翻译成“。net方式”,但它们大致上被IEnumerable < T >和IEnumerator < T >所取代。
Rather than
而不是
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++;
}
you would see (in c#)
你会看到(在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;
}
Or more explicitly (without hiding the IEnumerator behind the foreach syntax sugar):
或更明确地(不隐藏在foreach语法sugar后面的IEnumerator):
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;
}
As you can see, foreach just hides the .net enumerator for you.
正如您所看到的,foreach都为您隐藏了。net枚举器。
So really, the ".net way" would be to simply allow people to create List< Local > items for themselves. If you do want to control iteration or make the collection a bit more custom, have your collection implement the IEnumerable< T > and/or ICollection< T > interfaces as well.
所以,真正的“。net方法”是让人们为自己创建List< Local >项。如果您确实想控制迭代或使集合更自定义一些,那么让您的集合实现IEnumerable< T >和/或ICollection< T >接口。
A near direct translation to c# would be pretty much what you assumed:
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;}
}
}
Then a user would be able to
然后用户就可以
foreach( Local item in someNative.Locals)
{
...
}
#2
0
@Phillip - Thanks, your answer really got me started in the right direction.
@Phillip -谢谢,你的回答让我开始正确的方向。
After seeing your code, and doing a little more reading in Nish's book C++/CLI in Action, I think using an indexed property that returns a const tracking handle to a Local instance on the managed heap is probably the best approach. I ended up implementing something similar to the following:
在看到您的代码并在Nish的书c++ /CLI中做了一些阅读之后,我认为使用一个索引属性来返回托管堆上的本地实例的const跟踪句柄可能是最好的方法。我最终实现了类似如下的东西:
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;
};