Anlegen eines Objekts



  • Customer object1 = new Customer();
    

    Wieso muss man denn new schreiben. Schließlich sind alle Objekte Referenzen.
    Warum führt man nicht einfach

    Customer object1()
    

    als neue Syntax ein. In Objective C muss man ja auch nicht mehr alloc init schreiben das macht der Compiler im Hintergrund.



  • naja vll. hatte C# als vorbild C++ und nich objective C?

    klein plan



    • Die Syntax, die du vorschlägst, gibt es ja so ähnlich in C++, und dort sorgt sie für Mehrdeutigkeiten. Was meinst du, was z.B. hier passiert? Bestimmt ist das eine Variablendeklaration?
    Customer object1();
    

    Denkste – das ist ein Funktionsprototyp. Such mal nach "most vexing parse".

    • Außerdem wird in C# klar unterschieden zwischen Allokation und Initialisierung. Das hier legt nur eine Objektreferenz an (bzw. bei value types den Speicherplatz für die Instanz):
    Customer object1;
    

    Und das hier initialisiert ein Objekt:

    new Customer()
    

    Und wie bekommt man jetzt die Objektreferenz nach object1 ? Klar, Zuweisung. Das ist (IMO) einfacher zu lesen. Und es ist beim Lesen direkt klar, daß Statements wie Customer object1; niemals Funktionsaufrufe verursachen, anders als in C++, wo es stark davon abhängt, ob Customer POD ist oder ob es einen Konstruktor/Destruktor deklariert. Daß letzteres praktisch ist, bestreite ich nicht, aber wer regelmäßig Code reviewt, beginnt schnell über solche hidden calls zu fluchen.

    Seit ich mit C# angefangen habe, finde ich das RAII-Guard-Pattern in C++ bescheuert, weil etwas, das aussieht wie eine Variablendeklaration, sowohl beim Eintritt in den Scope wie auch bei dessen Verlassen Codeausführung verursacht:

    {
        ControlUpdateGuard guard(this); // Deklaration einer Variable, die nie benutzt wird? Kann also weg, oder? – Nein, denn es ruft BeginUpdate()/EndUpdate() auf.
        // ...
    }
    

    Das ist hier viel klarer:

    using (Updatable.Guard(this))
    {
        // ...
    }
    
    • Durch die Verwendung von new ist außerdem für den Compiler (und ebenso für den meist noch leichter zu verwirrenden Leser) immer klar, ob jetzt ein Typ erwartet wird oder ein Ausdruck. Folgendes Beispiel:
    using System;
    
    public class Foo {}
    
    public class Test
    {
        public static event Func<int> Foo;
    
        private static void Bar<T>(T value) {}
    
        public static void Main()
        {
            Foo = () => 42;
            Bar(Foo()); // <--
        }
    }
    

    Sollte die markierte Zeile jetzt das Event Foo aufrufen oder eine Instanz der Klasse Foo erstellen?

    Für den C#-Compiler ist klar, daß das Event gemeint ist; und wenn du Bar(new Foo()) schreibst, ist klar, daß der Typ gemeint ist. Bräuchte man kein new , wäre die Syntax mehrdeutig.


Log in to reply