2011-12-31 5 views
5
unsafe public class Temp 
{ 
    public struct Node 
    { 
     Node *left; 
     Node *right; 
     int value; 
    } 

    public Temp() 
    { 
     Node* T=new Node(); 
     T->left=null; 
     T->right=null; 
     T->value=10; 
    } 
} 

main() 
{ 
    Temp temp=new Temp(); 
} 

Nó cho lỗi mà tham chiếu đối tượng không được đặt thành thể hiện của đối tượng. Làm thế nào tôi có thể làm điều đó khi tôi muốn thực hiện Chương trình Cây AVL (mà tôi đã tạo ra và thử nghiệm trong C++ nhưng sao chép trong C# cho lỗi)Cấu trúc khởi tạo con trỏ trong C#

+0

_What_ cung cấp cho các lỗi? Tôi không thấy _any_ mã lỗi. – Oded

+12

Tại sao bạn sử dụng 'không an toàn'? Sao chép mã từ C++ sẽ không giúp bạn đi xa. Bạn có chắc bạn không muốn 'class' (trong C#, điều này có nghĩa là kiểu tham chiếu, cho phép' null') thay vì 'struct' (trong C#, điều này có nghĩa là kiểu giá trị, luôn luôn được sao chép bởi giá trị và không có khái niệm 'null')? – bobbymcr

Trả lời

4

Vấn đề là với các dòng:

Node* T=new Node(); 

Trong C#, new Node() trả về Node (tham chiếu), không phải là Node* (là con trỏ). Thay vào đó, bạn nên sử dụng stackalloc.

Dù sao, vui lòng không sao chép C++ và thực hiện theo cách C#!

+0

Tôi cũng đã tìm thấy điều đó. Tuy nhiên điều đó không cung cấp cho 'tham chiếu đối tượng không được thiết lập để dụ của một đối tượng' nhưng một ngoại lệ cast không hợp lệ. – rene

2

Bạn không thể gán biến .NET cho con trỏ, bạn chỉ có thể lấy địa chỉ của nó. Nếu bạn không tham khảo new ed Node nó sẽ được thu thập rác ngay lập tức, do đó bạn có thể đã chạy vào "tham chiếu đối tượng chưa được đặt". Tuy nhiên, biểu thức như Node* T = new Node() không nên biên dịch vì nó có hiệu quả cố gắng thực hiện chuyển đổi loại không hợp lệ.

Điều bạn đang cố gắng làm là sai: không sao chép và dán mã C++ vào C#, điều này là vô nghĩa. Nếu bạn đã thử nghiệm các thành phần C++ sử dụng .NET/intermanaged interop để so sánh dữ liệu giữa hai thế giới, mặc dù tôi sẽ không khuyên bạn nên làm điều đó ở mức trừu tượng này. Nếu bạn đang thực hiện một bài tập, chỉ thực hiện một cây AVL trong thế giới .NET, nếu không hãy sử dụng một trong các bộ sưu tập khung công tác có chức năng tương đương, ví dụ: SortedSet hoặc SortedDictionary ...

+0

Vì Node là một cấu trúc, nó không phải là rác được thu thập ở tất cả - đơn giản; địa chỉ đó trên ngăn xếp có khả năng được sử dụng lại ngay –

+0

Phải, tôi nói: Tôi nên đọc hai lần trước khi đăng. –

17

Đừng cố gắng sử dụng con trỏ trong C# như thế này. Nếu bạn đang chuyển mã C++ sử dụng con trỏ làm tham chiếu, thay vào đó hãy sử dụng các kiểu tham chiếu. Mã của bạn sẽ không hoạt động chút nào; "mới" không phân bổ cấu trúc ra khỏi heap, cho một điều, và thậm chí nếu nó đã làm con trỏ được yêu cầu phải được ghim tại chỗ trong C#; C# là một ngôn ngữ thu gom rác.

Trong ngắn không bao giờ sử dụng unsafe trừ khi bạn hiểu rõ mọi thứ cần biết về quản lý bộ nhớ trong C#. Bạn đang tắt hệ thống an toàn ở đó để bảo vệ bạn, và vì vậy bạn phải biết hệ thống an toàn đó làm gì.

Mã nên là:

public class Temp // safe, not unsafe 
{ 
    public class Node // class, not struct 
    { 
     public Node Left { get; set; } // properties, not fields 
     public Node Right { get; set; } 
     public int Value { get; set; } 
    } 

    public Temp() 
    { 
     Node node = new Node(); 
     node.Left = null; // member access dots, not pointer-access arrows 
     node.Right = null; 
     node.Value = 10; 
    } 
}