2008-09-17 29 views
5

Tôi quấn một lớp C++ bản xứ, trong đó có các phương pháp sau đây:Chuyển đổi std :: vector <> :: iterator để giao diện NET trong 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) các" NET là gì cách "đại diện cho cùng loại giao diện này? Một phương thức duy nhất trả về một mảng <>? Liệu mảng <> generic có trình vòng lặp, để tôi có thể triển khai BeginLocals() và EndLocals()?

2) Địa phương có nên được khai báo là giá trị cấu trúc trong trình bao bọc .NET không?

Tôi thực sự muốn đại diện cho lớp bao bọc bởi một hương vị .NET, nhưng tôi rất mới với thế giới quản lý - và loại thông tin này là bực bội để google cho ...

Trả lời

5

Vòng lặp aren 't chính xác có thể dịch sang "cách .net", nhưng chúng được thay thế bằng IEnumerable < T> và IEnumerator < T>.

Thay vì

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

bạn sẽ thấy (trong 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; 
} 

Hoặc một cách rõ ràng hơn (mà không cần che giấu IEnumerator đằng sau đường cú pháp 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; 
} 

Như bạn có thể thấy, foreach chỉ cần ẩn các .net enumerator cho bạn.

Vì vậy, thực sự, "cách mạng" sẽ đơn giản cho phép mọi người tạo Danh sách < Địa phương> các mục cho chính họ. Nếu bạn muốn kiểm soát lặp lại hoặc làm cho bộ sưu tập tùy chỉnh hơn một chút, hãy để bộ sưu tập của bạn triển khai giao diện IEnumerable < T> và/hoặc ICollection < T>.

Một bản dịch trực tiếp gần C# sẽ được khá nhiều những gì bạn cho rằng:

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

Sau đó, người dùng sẽ có thể

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

@Phillip - Cảm ơn, câu trả lời của bạn thực sự đã cho tôi bắt đầu đi đúng hướng.

Sau khi nhìn thấy mã của bạn, và làm một ít đọc hơn trong cuốn sách Nish của C++/CLI trong Action, tôi nghĩ rằng sử dụng một chỉ mục thuộc tính trả về một tay cầm theo dõi const để một trường hợp địa phương trên heap quản lý có lẽ là tốt nhất tiếp cận. Tôi đã kết thúc triển khai một cái gì đó tương tự như sau:

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

Đó là một cách tiếp cận tốt, nhưng có thể bạn cũng muốn đảm bảo hiển thị thuộc tính Đếm ít nhất :). Một lưu ý khác, không hiển thị danh sách hoặc thực hiện IEnumerable < T >, lớp sẽ không thể sử dụng được bởi các phần mở rộng LINQ trong .net 3.5 –

Các vấn đề liên quan