Frage

Also ich stecke mit Befestigungs / Aufrechterhaltung andere Programmierer Code (blech)

Ich bin ein fester Professor der Regel „Wenn es nicht kaputt ist es Sie nicht fix!“ so depsite wollen etwas, das ich jedes Mal zu ändern, kommen über horrende Code, Ich halte mich begrenzt auf nur die Änderung des absoluten Mindestbetrages von Code möglich, die erforderlichen Korrekturen vorzunehmen. Aber in einigen Fällen muss ich wirklich etwas verstehen, bevor Sie versuchen, es zu folgen / ändern.

Ich kam in diesem wenig hier:

region.LineSelected = (x) => { };

Und ich frage mich, ob es das gleiche wie das ist:

region.LineSelected = null;

Ich mag von 100% positiv sein, was die erste Zeile zu tun ist, bevor ich die Methode gehen zu ändern, es ist in.

War es hilfreich?

Lösung

Edit basiert auf meiner aktuellen Stellungnahme zu diesem Thema

Sie sind nicht das gleiche. Die Lambda-Version fügt einen Ereignishandler zu einer leeren anonymen Methode. Auf diese Weise können andere Code frei LineSelected () erhöhen, ohne sich Gedanken darüber, ob es sich um null (dh., Die keine Hörer).

Eg.

var lineSelected = this.LineSelected;

if (lineSelected != null)
{
    lineSelected(EventArgs.Empty);
}

Die obige Aussage kann eine Nullreferenceexception werfen, wenn etwas von LineSelected in einem anderen Thread Abo kündigt nach dem, wenn aber bevor das Ereignis ausgelöst wird. Zuordnung LineSelected einer temporären Variablen und dann die Erhöhung kann ein unsubscribed Ereignis-Listener aufrufen. Zuweisen der Event-Handler in eine lokale Variable ist die empfohlene Methode null Delegierten der Handhabung.

Durch das Hinzufügen einer leeren delegiert, ist ein anderer Code immer in der Lage LineSelected ohne Angst vor einer Nullreferenceexception zu nennen. Durch die Multicast-Ereignis Delegierten zu einem lokalen Variablen zuweisen, können Sie sicher sein, dass der Wert nicht sein kann modifiziert durch einen anderen Thread.

Andere Tipps

Ich kann nicht aus irgendeinem Grund denken, dass die erste Zeile Code zu haben. Das einzige, was ich denken kann, ist, wenn das LineSelected Ereignis auslöst, wenn Sie die erste Zeile Code in der Klasse haben, brauchen Sie nicht zu überprüfen, ob das LineSelected Ereignis null ist. dh:

if (this.LineSelected != null)
{
   LineSelected(this,new EventArgs());
}

Stattdessen können Sie einfach das Ereignis erhöhen, ohne null Kontrollen.

Doch mit der zweiten Zeile des Codes, müssen Sie für NULL-Werte überprüfen.

Das ist keine Event-Handler, das ist ein einfacher Delegierter. (Ein Event-Handler würde mit + geändert werden muß = und - = befestigen und lösen das Ereignis).

Wie bereits kommentiert worden, das Setzen der Delegat Eigenschaft auf einen leeren Handler bedeutet, dass null Kontrollen müssen nicht vor dem Aufruf der Delegierten durchgeführt werden (unter der Annahme, dass nichts anderes es setzen kann auf null).

Dies kann Code bequemen telefonieren, aber es soll nicht als eine Leistungsverbesserung verwechselt werden (indem die Notwendigkeit für null zu überprüfen entfernen). Im Allgemeinen wird das Overhead eines Delegatmethode Anruf wird deutlich höher sein als die von dem Null-Check. Möglicherweise gibt es einige Szenarien (zum Beispiel, wenn die Delegierten ein „echtes“ Implementierung 99,99% der Zeit hat), wo die Nullprüfung vermeiden könnte die Leistung verbessern, aber es ist schwer, ein Szenario vorstellen, in dem die klein wenig Unterschied in der Leistung gibt es genug Materie könnte es wert sein, der die Delegate-Aufruf auch nicht ganz rechtfertigen würde für etwas effizienter.

Entfernen

Ich denke, dies ist eine Technik auf jeden Fall null Kontrollen zu vermeiden.

Wenn der LineSelected Ereignis-raising-Code nicht über eine ordnungsgemäße NULL-Prüfung, dann wird dies eine Ausnahme verursachen:

region.LineSelected = null;

/* no event handlers added to LineSelected */

class Region {
    void OnLineSelected() {
        // Null error!
        LineSelected();
    }
}

Wenn es jedoch ein leerer Leernebeneffekt Handler hinzugefügt, dann wird der obige Code gut funktionieren, auch wenn niemand einen Handler auf das Ereignis hinzufügt, weil es immer sein, dass leere Prozedur zugewiesen.

Um sich zu erweitern, was Richard und Andrew sagte, es ist das Äquivalent von

region.LineSelected = delegate {};

Was bedeutet, dass, wenn Sie das Ereignis auslösen, Sie brauchen nicht zuerst für null zu überprüfen, weil es einen Delegierten (zum Preis eines kleinen Leistungseinbußen)

hat

Nein, es ist nicht das Gleiche. - Die erste Zeile weist LineSelected einen leeren Delegierten, die von null sehr unterschiedlich ist

Der einfachste Weg, um den Unterschied zu erkennen ist auf dem Code zu suchen, die Compiler in Ihrem Namen erzeugen, wenn Sie die Lambda-Syntax verwenden. Dieser Code:

using System;

class Program
{
    static void Main()
    {
        Action<int> func0 = (x) => { };
        Action<int> func1 = null;
    }
}

Wirklich kompiliert diese:

internal class Program
{
    // Methods
    private static void Main()
    {
        Action<int> func0 = delegate (int x) {
        };
    }
}

Beachten Sie, dass der Compiler klug genug war func1 zu entfernen, wie es eingestellt wurde null und nicht an anderer Stelle verwiesen wird. Aber beachten Sie, dass func0 bleibt und auf einen Delegierten festlegen, wenn auch nichts tut, aber ist sehr verschieden von null.

Sie sind nicht das gleiche, da der Event-Handler festgelegt ist.

Hier können Sie die Klasse sagen, dass die LineSelected macht, vergessen zu:

if( LineSelected != null )
    LineSelected(...)

Wenn diese Klasse waren die LineSelected anrufen und niemand zuhört, dann wird es Nullreferenceexception werfen

Beachten Sie, dass auch (Innenbereich) tun können, die Race-Bedingung zu vermeiden:

var event = LineSelected;     if (Ereignis! = null)         Ereignis (...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top