Laden...

[erledigt] Wertetypen mit oder ohne new erzeugen

Letzter Beitrag vor 13 Jahren 16 Posts 2.761 Views
[erledigt] Wertetypen mit oder ohne new erzeugen

Hallo ihr,
Ich habe in C# jetzt festgestellt, dass es irgendwie keinen Unterschied macht, ob man

meinestruktur m = new meinestruktur();

oder einfach nur

meinestruktur m;

schreibt.
Beides sind Wertetypen.
Im Internet finde ich nun allerdings immer Beispiele in denen Wertetypen mit new erstellt werden. (Es sei denn es ist einfach ein int, da wird das new immer weggelassen.)
Liegt das einfach daran, dass fast alle Strukturen sowieso immer eine Erstellungsroutine brauchen und das nur bei numerischen Typen nicht so oft der Fall ist?
Oder gibt es zum Beispiel zwischen

int i = new int();

und

int i;

einen wichtigen Unterschied? (Bis auf den Standardkonstruktor 0)

Vielen Dank
777

Nur Klassenmember werden automatisch initialisiert. Wenn du in einer Methode int i; schreibst und diese Variable irgendwo verwenden willst, bekommst eine Fehlermeldung die so lautet:

Use of unassigned local variable 'i'

Aber einfach mal ausprobieren, dann kommt man gleich selber drauf.

Lg XXX

schon klar... aber das meine ich nicht.
Was ich meine ist: Wo ist der Unterschied zwischen:

Meinestruktur m = new Meinestruktur();

und

Meinestruktur m;

Ist da echt der Einzige unterschied dass im ersten Fall alle Member initialisiert, im zweiten aber nicht werden?

Es gibt keinen Unterschied. Es wird so oder so mit dem Defaultkonstruktor erstellt.

Ein Unterschied wärs nur dann, wenn du

new Struktur(/*mit irgendwelchen Parametern*/);

aufrufen würdest.

Lg XXX

Okay... dankeschön.
Wobei 'kein Unterschied' ja nicht richtig ist.

    class Program
    {
        static void Main(string[] args)
        {
            wert w;
            //FEHLER!!!! i ist noch nicht zugewiesen.
            Console.WriteLine(w.i);
            Console.Read();
        }
    }
    class wert
    {
        public int i;
    }
    class Program
    {
        static void Main(string[] args)
        {
            wert w = new wert();
            Console.WriteLine(w.i);
            Console.Read();
        }
    }
    class wert
    {
        public int i;
    }

Hier funktioniert ja schließlich nur der zweite Fall. Und da wird i mit 0 initialisiert.

Hallo 777,

in diesem Beispiel ist wert eine Klasse und nicht initialisiert worden.
Der Fehler den du bekommst ist eine NullReferenceException.
Klassen müssen initialisiert werden um auf eine Instanzeigenschaft zugreifen zu können.

Gruß
Michael

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

Uuupps... mein Fehler.
Ich meinte natürlich:

    class Program
    {
        static void Main(string[] args)
        {
            wert w;
            //FEHLER!!!! i ist noch nicht zugewiesen.
            Console.WriteLine(w.i);
            Console.Read();
        }
    }
    struct wert
    {
        public int i;
    }

    class Program
    {
        static void Main(string[] args)
        {
            wert w = new wert();
            //FUNKTIONIERT!  Denn alle Member von w werden durch 'new' zugewiesen.
            Console.WriteLine(w.i);
            Console.Read();
        }
    }
    struct wert
    {
        public int i;
    }

Hallo 777,

Okay... dankeschön.
Wobei 'kein Unterschied' ja nicht richtig ist.

liest du eigentlich was man dir mitzuteilen versucht?

Nur Klassenmember werden automatisch initialisiert. Wenn du in einer Methode int i; schreibst und diese Variable irgendwo verwenden willst, bekommst eine Fehlermeldung die so lautet:

Zitat:
Use of unassigned local variable 'i'

Lg XXX

//EDIT: Um noch deutlicher zu werden:


    class Program
    {
        static wert w; 
        //oder
        wert w2;
        //beide Variablen werden mit dem Defaultkonstruktor initialisiert.

        static void Main(string[] args)
        {
            Console.WriteLine(w.i);
            Console.WriteLine(new Program().w2.i);
            Console.Read();
        }
    }
    struct wert
    {
        public int i;
    }

Okay... aber aus welchem Grund wird er hier nicht aufgerufen?

    class Program
    {

        static void Main(string[] args)
        {
            wert w;            
            Console.WriteLine(w.i);
            Console.Read();
        }
    }
    struct wert
    {
        public int i;
    }

//Edit:
In diesem Fall geschieht das erstellen ja innerhalb der Methode.

Hier zwei Links in denen deine Fragen genauer erklärt werden zum Nachlesen:
Value Types
und
Instance Constructors

Lg XXX

Also meine Idee woran das liegen könnte ist die, dass wenn 'Program' erstellt wird, werte und ihre Member ebenfalls definiert werden. Innerhalb der Mainfunktion jedoch geschieht das natürlich nicht.

Ich denke es wäre interessant zu wissen aus welchen Grund Structs als Instanzvariablen einen Default-Wert bekommen, Structs als lokale Variablen aber nicht und was der Sinn der Unterscheidung dahinter ist.

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

Hallo zusammen,

in Wahrheit wird in in


public struct Foo
{
   public int Value;
}
public sealed class Bar
{
   private Foo _foo;
}

kein Konstruktor von Foo aufgerufen - der Speicherbereich, den _foo belegt, wird einfach im Zuge der Instanzierung eines Bar genullt.
Aus diesem Grund kann man auch keinen Standardkonstruktor für Strukturen definieren; diese würden evtl. nie aufgerufen werden.

Anders verhält es sich mit


Foo foo;

innerhalb einer Methode: Hier wird foo (bzw. dessen Member) auf den Stack gelegt. Da dieser jedoch nicht automatisch genullt wird, muss man dies selbst explizit durch Aufruf des parameterlosen Konstruktors tun.

Letzendlich handelt es sich hierbei um eien Sicherheistvorkerhrung, um sicherzustellen, dass man nicht aus Speicher mit undefinierten Werten lesen kann.

(In etwa so nachzulesen in "Microsoft .NET Framework Programmierung" von Jeffrey Richter)

innerhalb einer Methode: Hier wird foo (bzw. dessen Member) auf den Stack gelegt. Da dieser jedoch nicht automatisch genullt wird, muss man dies selbst explizit durch Aufruf des parameterlosen Konstruktors tun.

Das klingt einleuchtend. Danke für die Erklärung! 👍

Weeks of programming can save you hours of planning

Danke winSharp93 für die kurze einleuchtende Erklärung. Ich wusste zwar immer wie das Problem zu lösen ist, aber verstanden habe ich es nie warum man Felder nicht und Lokale Structs schon initialisieren muss. Nun ist es etwas klarer.

Mein Blog
Meine WPF-Druckbibliothek: auf Wordpress, myCSharp

Vielen Dank für das Beispiel winSharp93
So etwas in der Richtung hatte ich bereits vermutet.
Diese Frage ist damit für mich beantwortet 😉