Entwickler-Ecke

Sonstiges (.NET) - Das mysteriöse null...


Implementation - So 10.10.10 20:21
Titel: Das mysteriöse null...
Ich habe drei Interfaces deklariert:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
public interface QuinControl
{
  ...
}
public interface QuinDynamicControl : QuinControl
{
  ...
}
public interface QuinSensitiveControl : QuinDynamicControl
{
  ...
}

Und nun eine Basisklasse, die unter anderem diese Interfaces implementiert:

C#-Quelltext
1:
2:
3:
4:
public class QuinDynamicControlV : QuinControlV, QuinDynamicControl, QuinSensitiveControl, ...
{
  ...
}

Und mehrere Kindklassen, die von dieser Basisklasse ableiten.
Außerdem habe ich eine Klasse für Container.
Dieser Container enthält Objekte, die alle QuinControl implementieren, teilweise auch QuinDynamicControl und QuinSensitiveControl.
Nun müssen einige Methoden der Containerklasse feststellen, ob ein bestimmtes Objekt auch QinDynamicControl implementert.

Das funtioniert mit dem Is-Operator auch ganz super.
Nun habe ich dort an einer Stelle auch ein Objekt, dass ganz sicher QuinDynamicControl implementiert, ich aber wissen muss, ob es auch QuinSensitiveControl implementiert.
Das frage ich ebenfalls mit Is ab.
Nun liefert mir Is an dieser Stelle aber leider immer false zurück.

Wenn ich diese Abfrage im FormLoad oder ButtonClick vornehme, bekomme ich das richtige Ergebnis (true).
Nur in dieser einen Methode nicht.

Hat jemand irgendeine Idee, was hier falsch laufen könnte?

[edit]
Irgendetwas geht hier nicht mit rechten Dingen zu sich...

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
if (hovered != null// Wird ausgeführt, also sollte hovered != null sein ...
{
        MessageBox.Show((hovered == null).ToString()); // Gibt "false" aus
        MessageBox.Show(hovered.Name); // Gibt eine NullReferenceException, weil hovered == null ist?????
        MessageBox.Show((hovered == null).ToString());
        // Hier übrigens die oben beschriebene Abfrage,
        // IsSensitive und AsSensitive sind Extension Methods
        if (hovered.IsSensitive())
                hovered.AsSensitive().MouseDown(e.X - hovered.Left, e.Y - hovered.Top);
}

Das soll mal einer verstehen ...
Ist hovered jetzt == null oder != null?
Nein, ich benutze keine Threads.
Und nein, ich gebe nirgendwo von Hand Objekte frei.


Greenberet - So 10.10.10 20:44

ich würde sagen, dass "Name" null ist


Implementation - So 10.10.10 20:45

Der Debugger sagt mir: hovered ist "null".
Und Name ist "field".

Man sehe einen seltsamen Effekt:

C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
if (hovered != null)
{
        //MessageBox.Show((hovered == null).ToString());
        MessageBox.Show(hovered.Name); // Gibt "field" aus
        MessageBox.Show((hovered == null).ToString()); // Gibt "true" aus
        if (hovered.IsSensitive())
              hovered.AsSensitive().MouseDown(e.X - hovered.Left, e.Y - hovered.Top);
}

Kein Fehler ...


Yogu - So 10.10.10 20:56

Name ist eine Eigenschaft, oder? Wie sieht denn der Getter dazu aus? Wird auf hovered vielleicht threadübergreifend zugegriffen?


Implementation - So 10.10.10 20:58

user profile iconYogu hat folgendes geschrieben Zum zitierten Posting springen:
Name ist eine Eigenschaft, oder? Wie sieht denn der Getter dazu aus? Wird auf hovered vielleicht threadübergreifend zugegriffen?

Der Getter, ganz primitiv:

C#-Quelltext
1:
2:
3:
4:
5:
public virtual string Name
{
      get { return name; }
      set { name = value; }
}

Und ich benutze keine weiteren Threads.

Siehe auch mein Edit.
Wenn ich MessageBox.Show((hovered == null).ToString()); auskommentiere, kommt kein Fehler.

[edit]
Ich habe das Problem nun auch in der Delphi-PRAXiS gestellt: http://www.delphipraxis.net/155140-das-mysterioese-null.html#post1054956


Kha - So 10.10.10 22:17

Hu :gruebel: .

hovered ist eine lokale Variable und es sind auch keine Operator-Überladungen im Spiel? Um ganz sicher zu gehen, würde ich mir gern mal den IL-Code anschauen, aber gegen ein lauffähiges Beispiel sage ich auch nichts ;) .


Implementation - So 10.10.10 23:53

hovered ist ein nichtstatisches Feld. Operatorüberladungen sind keine im Spiel (geht das bei Interfaces überhaupt?).
Eine lauffähige Exe könnt ihr morgen früh bekommen. Heute abend nicht mehr ...

[EDIT]
So, hier die versprochene Echse ...


Kha - Mo 11.10.10 17:10

Ich würde mal behaupten, dass die erste MessageBox ein MouseLeave erzeugt, wordurch dann hovered = null gesetzt wird. Aber ohne Code kann ich das nicht eindeutig bestätigen.


Implementation - Mo 11.10.10 17:23

Du hast Recht. Das war's.
Ich habe schon fast an Übernatürliches geglaubt und du schaust dir das Programm einmal kurz an und präsentierst mir ganz nüchtern die Lösung :autsch:
Vielen Dank!! :beer: