2011-12-31 14 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(); 
} 

Daje błąd, że odwołanie do obiektu nie jest ustawione na wystąpienie obiektu. Jak mogę to zrobić, gdy chcę zrobić Drzewo AVL programu (który stworzyłem i przetestowany w C++, ale kopiowanie w C# daje błąd)Inicjalizacja wskaźnika strukturalnego w języku C#

+0

_What_ daje błąd? Nie widzę kodu _any_, który mógłby spowodować błąd. – Oded

+12

Dlaczego używasz 'unsafe'? Kopiowanie kodu z C++ nie doprowadzi cię daleko. Czy na pewno nie chcesz 'class' (w języku C#, oznacza to typ odwołania, który dopuszcza wartości' null') zamiast 'struct' (w języku C# oznacza to typ wartości, który zawsze jest kopiowany według wartości i nie ma pojęcia "null")? – bobbymcr

Odpowiedz

4

Problem jest z linii:

Node* T=new Node(); 

W języku C#, new Node() zwraca Node (co jest odniesieniem), a nie Node* (która jest wskaźnikiem). Zamiast tego należy użyć stackalloc.

W każdym razie, proszę nie kopiuj C++ i zrób to C# way!

+0

Znalazłem również to. To jednak nie daje "Odwołania do obiektu nie jest ustawione na instancję obiektu", ale wyjątek dotyczący nieprawidłowego rzutowania. – rene

2

Nie można przypisać zmiennej .NET do wskaźnika, który może przyjąć tylko jego adres. Jeśli nie odwołasz się do new ed Node, natychmiast zostanie pobrane śmieci, więc prawdopodobnie masz uruchomione "odniesienie do obiektu nie jest ustawione". Wyrażenie takie jak Node* T = new Node() nie powinno się jednak kompilować, ponieważ skutecznie próbuje wykonać niepoprawną konwersję typu.

Co próbujesz zrobić, to źle: nie kopiuj i nie wklejaj kodu C++ do C#, to jest nonsens. Jeśli masz już przetestowane komponenty C++, używaj .NET/unmanaged interop do przekazywania danych pomiędzy dwoma światami, chociaż nie polecałbym tego na tym poziomie abstrakcji. Jeśli wykonujesz ćwiczenie, zaimplementuj drzewo AVL tylko w świecie .NET, w przeciwnym razie użyj jednej z kolekcji szkieletów o równoważnej funkcjonalności, np. SortedSet lub SortedDictionary ...

+0

Ponieważ węzeł jest strukturą, to w ogóle nie jest zbiorem śmieci - po prostu; ten adres na stosie prawdopodobnie wkrótce zostanie ponownie wykorzystany. –

+0

Dobrze, mea culpa: Powinienem przeczytać dwa razy przed wysłaniem. –

17

Nie próbuj używać wskaźników w języku C# w ten sposób. Jeśli portujesz kod C++, który używa wskaźników jako referencji, zamiast tego użyj typów referencyjnych. Twój kod nie zadziała w ogóle; "new" nie przypisuje struktur ze sterty, na jedną rzecz, a nawet jeśli to było wskaźniki są wymagane do przypięcia w miejscu w języku C#; C# jest językiem zbierającym śmieci.

W skrócie Nigdy nie używaj unsafe, chyba że dokładnie wiesz wszystko, co musisz wiedzieć o zarządzaniu pamięcią w C#. Wyłączasz system bezpieczeństwa, który jest po to, by cię chronić, a więc musisz wiedzieć, co robi ten system bezpieczeństwa.

Kod powinien być:

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; 
    } 
} 
Powiązane problemy