5

我正在包装一个本机 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 方式”是什么?返回数组<>的单个方法?array<> 泛型是否有迭代器,以便我可以实现 BeginLocals() 和 EndLocals()?

2) Local 是否应该在 .NET 包装器中声明为值结构?

我真的很想用 .NET 风格来表示包装类,但我对托管世界很陌生——这种类型的信息让谷歌感到沮丧......

4

2 回答 2

5

迭代器不能完全转换为“.net 方式”,但它们大致被 IEnumerable < T > 和 IEnumerator < T > 取代。

而不是

  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 方式”只是允许人们为自己创建 List<Local> 项目。如果您确实想控制迭代或使集合更加自定义,请让您的集合也实现 IEnumerable< T > 和/或 ICollection< T > 接口。

几乎直接翻译为 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)  
{
 ... 
}
于 2008-09-17T17:03:41.627 回答
0

@Phillip - 谢谢,你的回答真的让我朝着正确的方向开始。

在看到您的代码并在 Nish 的书C++/CLI in Action中进行更多阅读后,我认为使用一个索引属性返回一个 const 跟踪句柄到托管堆上的 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;
};
于 2008-09-17T19:45:20.380 回答