Entwickler-Ecke

C# - Die Sprache - Instanzieren der ControlCollection erzeugt StackOverflow


Delete - Mo 02.08.10 14:16
Titel: Instanzieren der ControlCollection erzeugt StackOverflow
Hallo,

Folgendes Konstrukt:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
using System.Windows.Forms;

abstract class AHelper
{
  public AHelper()
    : base()
  {
    // öst die StackOverflow-Exception aus.
    this.ErrorControls = new Control.ControlCollection(null);
    // als Alternative würde der Zugriff auf den privaten Member _ErrorControls keine Exception auslösen.
    this._ErrorControls = new Control.ControlCollection(null);
  }

  private Control.ControlCollection _ErrorControls;
  public virtual Control.ControlCollection ErrorControls
  {
    get
    {
      return this._ErrorControls;
    }
    set
    {
      this._ErrorControls = ErrorControls;
    }
  }
}

class FormHelper : AHelper
{
  public FormHelper()
    : base()
  {
  }
}

class Form1 : Form
{
  public Form1()
  {
    this.Helper = new FormHelper();
  }

  private FormHelper _Helper;
  public virtual FormHelper Helper;
  {
    get
    {
      return this._Helper;
    }
    set
    {
      this._Helper = Helper;
    }
  }


Das Problem:

In der Klasse AHelper wird eine StackOverflow-Exception ausgelöst, sobald er die ControlCollection instanziert. Die Exception wird allerdings nicht ausgelöst, wenn ich den privaten Member _ErrorControls direkt instanziere.

Mir ist klar, dass ich _ErrorControls in meinem Fall nicht mit Get und Set implementieren müsste. Aber ich will mir die Erweiterbarkeit offen lassen.

Danke Christian

Edit:

Das die StackOverflowException durch zu tief verschachtelte Methodenaufrufe ausgelöst wird ist mir klar. Allerdings weiß ich nicht, wo ich zu tief verschachtelt haben sollte.


danielf - Mo 02.08.10 14:56

Hallo,

also warum genau die StackOver-Flow-Exception geschmissen wird kann ich so nicht nachvollziehen. Am Besten du nimmst den Debugger dafür.

Allerdings machst du einen groben Fehler, dass du im Set-Teil den aktuellen Wert Des properties dem Member zuweist.
An den stellen machst du normal set { this._ErrorControls = value; }. Abgesehen davon, dass die Implementierung unnötig ist, da du Nihcts spezielles im get/set machst. Es würde public Control.ControlCollection ErrorControls { get; set; } ausreichen.

Gruß


Delete - Mi 04.08.10 08:33

Ich habe jetzt erst festgestellt, dass eine Zuweisung A=B auch auf der linken Seite ein read der Eigenschaft A auslöst. Jedenfalls habe ich in get statt _A wiederum A zurückgegeben. _A ist der private Member, der von A repräsentiert wird. Und dort wurde natürlich der Code ohne Abbruch rekursiv.

user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:
An den stellen machst du normal set { this._ErrorControls = value; }.

Habe ich gemacht. Danke.

user profile icondanielf hat folgendes geschrieben Zum zitierten Posting springen:
Abgesehen davon, dass die Implementierung unnötig ist, da du Nihcts spezielles im get/set machst. Es würde public Control.ControlCollection ErrorControls { get; set; } ausreichen.

Nein, würde es nicht. Auf der einen Seite hast Du recht. Andererseits will ich nicht jedes Mal, wenn ich mich doch entschließe die Werte zu validieren, erst anfangen eine explizite Eigenschaft zu implementieren. So ist alles für eine Erweiterung des Quelltextes vorhanden, indem ich nur neuen Code einfüge statt alten vorher verändern zu müssen. Geschmackssache ...

Danke für die Unterstützung.