Reihenfolge der Initialisierung von Membern



  • Mal eine Frage. Wenn ich sowas hier habe:

    class A
    {
    	public A(string text)
    	{
    		Console.WriteLine(text);
    	}
    }
    
    class B
    {
    	private A a1 = new A("a1");
    
    	private A a2 = new A("a2");
    }
    

    Ist dann eigentlich definiert, in welcher Reihenfolge die Konstruktoren aufgerufen werden? Wird das zufällig festgelegt oder nach der Reihenfolge im Quellcode? Denn die sollte ja eigentlich völlig unerheblich sein und keinen Einfluss auf den Programmablauf haben. (Weshalb man ja auch einen Member nicht mit einem anderen initialisieren kann. Das hier:

    private A a2 = a1;
    

    geht zum Beispiel nicht.)



  • ich glaub nicht das das definiert ist - wie du selber schon schriebst spielt das im programm ablauf ja auch keine rolle



  • Hm, interessant. Das würde aber bedeuten, dass das in gewisser Weise eine Form von undefiniertem Verhalten ist. Denn ich kann nicht vorhersagen, welcher String zuerst ausgegeben wird. Der Compiler kann sich eine Reihenfolge aussuchen. Der C#-Standard definiert jedoch, dass es, wenn man nicht gerade unsafe-Code verwendet, in C# kein undefiniertes Verhalten gibt.



  • Die Reihenfolge entscheidet in diesem Beispiel. Siehe dazu §17.4.5 Variable initializers.



  • Sorry, die Numerierung ist nicht in allen Versionen gleich.
    Zu finden ist der Abschnitt bei Classes -> Fields -> Variable initializers.



  • Aha: "textual order". Und bei mehreren Klassendateien: "unspecified". 🙄 Soviel zu undefiniertem Verhalten.



  • Du misverstehst "undefined behaviour" (UB).

    UB würde bedeuten, dass das Programm einfach irgendwas machen darf.

    In dem Fall ist definiert, dass die Konstruktoren alle irgendwann ausgeführt werden. Die Reihenfolge ist nicht definiert, OK. Und? Deswegen ist das noch lange kein UB.



  • Man kann aber anhand des Lesens des Quelltextes nicht vorhersagen, was genau das Programm tun wird. Der Compiler kann es sich aussuchen.



  • Man kann aber anhand des Lesens des Quelltextes nicht vorhersagen, was genau das Programm tun wird. Der Compiler kann es sich aussuchen.

    Und?

    Dann muss der Programmierer eben dafür sorgen, dass das Verhalten trotzdem jedesmal genau dasselbe ist. Man muss ja statische Konstruktoren nicht dazu verwenden irgendwas zu machen, wo wichtig ist wann genau es passiert.


Anmelden zum Antworten