[C#] Alternativer Konstruktor

krizzelfix

Commander
Registriert
Sep. 2005
Beiträge
2.626
Moin allerseits,

ich hab eine Klasse geschrieben die Serialzieable ist, in der Dateiinfomationen speicher. Dadruch kann ich ja keine Parameter im Konstruktor entgegen nehmen. Jetzt wollte ich aber noch eine Klasse benutzen in deren Konstruktor ich den Vollständigen Dateinamen brauch.

Gibt es eine andere Möglichkeit als eine Methode zu schreiben in der Überprüft wird ob alle benötigten Daten vorhanden sind um dann die zweite Klasse zu laden?

Finde das ziemlich unsauber programmiert.

Grüße

tewes
 
Ich verstehe nicht ganz, was Du meinst. Du meinst bestimmt nicht, dass Du auch noch einen Constructor einfügen willst, an den Du den vollständigen Dateinamen übergeben kannst, oder? Das wäre ja einfach mit Überladung möglich:
Code:
class MyClass
{
  public MyClass() { /* parameterloser Constructor */ }
  public MyClass(string fileName) { /* alternativer Constructor */ }
}
Am besten schilderst Du Dein Anliegen mal an einem kleinen Beispiel. :)
 
Hallo Prypjat,

danke für deine Antwort. Aber mit überladung ist es nicht getan, vermute ich mal.
So sieht meine Klasse z.Z. aus(aus erinnerung;)):
Code:
[Serializeable]
class SongInfo
{
      public SongInfo() {}
      // Einige Methoden & Eigenschaften...
}
Da die Klasse serializeable ist kann ich ja keine Daten den Konstruktor übergeben.
Jetzt wollte ich noch ID3-Tags laden. Die können ja nur geladen werden wenn ich den Dateinamen habe ;)
Um die Tags zu laden muss ich jetzt erst eine Methode aufrufen in der dann geprüft wird ob alles OK ist. Und das möchte ich verhindern.

Grüße

tewes
 
Ich finde das nicht weiter schlimm oder "dreckig" programmiert. Du kannst doch einfach in dem parameterlosen Constructor das Feld mit dem Dateinamen überprüfen und ggf. die ID3-Tags laden:
Code:
[Serializeable]
class SongInfo
{
  private string fileName;
  public SongInfo()
  {
    // Prüfen, ob Dateiname vorhanden ist
    if (!this.fileName.Equals(string.Empty))
    {
      // Lade die ID3-Informationen aus der Datei
    }
  }
}
Ich persönlich finde das vollkommen in Ordnung. Es geht eben einfach nicht anders. Wie Du schon sagst: ist ja logisch, dass man die Datei benötigt.
 
So wie du das in deinem Bespiel gemacht hast wirds aber nicht funktionieren, da etwas im Konstruktor der Klasse steht. Dadurch wird eine Exception geschmissen.
Dann werd ich das jetzt so lassen:
Code:
[Serializeable]
class SongInfo 
{
       private string _Path = "";
       private string _FileName = "";
       private ID3v2Tag ID3Tag;
       public SongInfo() {}
       public bool LoadID3Tags ()
       {
              if(File.Exsists(_Path + _FileName)
              {
                     ID3Tag = new ID3v2Tag(_Path + _FileName);
                     return true;
              }
              return false;
       }
       public string FileName 
       {
              get
              {
                     return _FileName;
              }
              set
              {
                     //Prasen des Pfades
                     _FileName = value;
              }
       }
       public string Path 
       {
              get
              {
                     return _Path;
              }
              set
              {
                     //Prasen des Pfades
                     _Path = value;
              }
       }
}
//Benutzen der Klasse
SongInfo info = new SongInfo
info.Path = @"C:\";
info.FileName = "test.mp3";
info.LoadID3Tags()

Habe jetzt aber noch eine andere Frage:
Und zwar benutze ich jetzt die Klasse Audio aus dem DirectX um die Lieder abzuspielen. Für diese Klasse habe ich mir zum verwalten die Klasse DirectX_Player geschrieben. Die Audio Klasse hat im Konstruktor den Dateinamen als Parameter. In meiner Klasse DirectX_Player erstell ich eine neue Instanz der Audio Klasse. Nun möchte ich aber in meiner Klasse keinen Dateinamen als Parameter mit übergeben.

So nun zu meiner Frage:
Kann ich das irgendwie umgehen, ausser wenn ich in jeder Eigenschaft und Methode die Instanz auf NULL überprüfe?

Ich hoffe das war verständlich, ansonsten Poste ich nach er Arbeit mal Quellcode. Der sagt ja bekanntlich mehr als 1000 Worte ;)

Grüße

tewes
 
Oh, ich wusste nicht, dass ein parameterloser Constructor für die Serialisierung leer sein muss. Wieder was dazu gelernt. Das habe ich bisher noch nie benötigt, daher ist es mir wohl noch nicht aufgefallen. Allerdings bringt das ja einige Probleme mit sich, wenn man beispielsweise irgendwas zur Initialisierung eines Objekts tun muss...

Zu Deinem zweiten Problem: Ich verstehe vermutlich, was Du meinst, aber mir fällt da keine Lösung ein. Du erzeugst bestimmt im Constructor der DirectX_Player-Klasse ein Audio-Objekt und weist es einem Feld zu, richtig? Nun benötigst Du aber zum Instanziieren des Audio-Objekts einen Dateinamen, den Du nicht an den Constructor Deiner DirectX_Player-Klasse übergeben willst. Damit hast Du natürlich ein Problem, weil Du so kein Audio-Objekt erzeugen kannst. Daher wäre das dafür vorgesehene Feld nach der Instanziierung = null. An irdendeiner Stelle wirst Du ja mal einen Dateinamen setzen müssen, damit Du das Audio-Objekt überhaupt verwenden kannst.

Also mir fällt im Moment auch keine Möglichkeit ein, wie man sich die Sicherheitsabfragen ersparen könnte. Eventuell könntest Du mit try {} catch {} arbeiten, da eine NullPointerException auftreten dürfte, wenn das für Audio vorgesehene Feld null ist und eine Methode/Eigenschaft aufgerufen wird.
 
Zuletzt bearbeitet:
Ja das stimmt, quasi garde genau mein fall mit dem Intialisieren ;). Aber ich denke das es nicht geht weil beim deserialisieren des Objects Fehler auftreten.

Zum zweiten werde ich das wohl mit if(Player != null) alles abfangen müssen. Da die Audio Klasse die Eigenschaft hat nur DirectXExceptions(die keine Messages, InnerExceptions o.ä besitzen und echt beschi** Dokumentiert sind) zu schmeissen wird es schlecht per Try/catch gehen.

besten Dank für deine Hilfe

Grüße

tewes
 
Zurück
Oben