Autor Beitrag
Najo
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Fr 24.04.09 23:42 
Schönen guten Abend!

Ich habe noch nicht viel Erfahrung mit C# und habe eine Konzeptionsfrage. Ich habe eine Basisklasse, die einen Member oder eine Methode besitzen soll, die von allen abgeleiteten Klassen implementiert werden soll. Zusätzlich möchte ich, dass der in den abgeleiteten Klassen zu konkretisierende Member oder die Methode statisch ist, so dass ich sie aufrufen kann, ohne eine Instance der Klasse erzeugen zu müssen. Mein Versuch sah wie folgt aus:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
abstract class CBaseFile
{
  public static abstract string FileExt();
}

class CFileABC : CBaseFile  
{
  public static override string FileExt()
  {
    return ".ABC";
  } 
}


Leider scheinen sich die "static" und "abstract" Keywords nicht zu vertragen und es kommt zu einem Compilerfehler. Gibt es eine Möglichkeit dieses Konzept umzusetzen?

Viele Dank
Najo
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Sa 25.04.09 00:48 
Hallo und :welcome: im Forum!

Das Problem ist, dass eine statische Methode nicht von einer Objektinstanz abhängt. Deshalb kann man diese nicht überschreiben.

Ein kleines Beispiel:
ausblenden 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:
public abstract class Test
{
  public abstract void callme();
}

public class Test1 : Test
{
  public override void callme()
  {
  }
}

public class Test2 : Test
{
  public override void callme()
  {
  }
}

Test a = new Test1();
a.callme(); // Test1.callme

a = new Test2();
a.callme(); // Test2.callme
Du hast also eine Variable vom Typ der Elternklasse und es wird zur Laufzeit bestimmt, welche Methode dann konkret aufgerufen wird.

Wenn du aber eine abstrakte Methode hast, dann hast du ja keine Instanzvariable. Du musst den Typ also direkt hinschreiben beim Aufruf. Deshalb verstehe ich da nicht so ganz was du da mit einer abstrakten Methode überhaupt erreichen willst, selbst wenn es ginge?
Najo Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Sa 25.04.09 08:18 
Guten Morgen,

ich möchte gerne eine generische Methode zum Laden von Daten aus einer Datei schreiben, deren Typ eingeschrängt ist auf die Basisklasse, damit sie immer über die "Eigenschaft" FileExt besitzt. Etwas so:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
public void LoadData<T>(string _basename) where T: CBaseFile
{             
  String fn = _basename + T.FileExt;
  
  // ...        
}


Deine Erklärung mit der der Instanzvariablen macht natürlich Sinn. Wahrscheinlich werde ich mir dann etwas anderes für das Dateihandling überlegen.

Danke für die Antwort!
Najo
Robert.Wachtel
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 895
Erhaltene Danke: 7

Windows 7 Ultimate x64
D5 Ent, D7 Arch, RAD Studio 2010 Pro, VS 2008
BeitragVerfasst: Sa 25.04.09 11:49 
user profile iconNajo hat folgendes geschrieben Zum zitierten Posting springen:
[...] ich möchte gerne eine generische Methode zum Laden von Daten aus einer Datei schreiben, deren Typ eingeschrängt ist auf die Basisklasse, damit sie immer über die "Eigenschaft" FileExt besitzt. [...]

Jaja, immer die Krux mit den Einschrängungen... :mrgreen: :mrgreen: :mrgreen:

Zitat:
[...] Etwas so:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
public void LoadData<T>(string _basename) where T: CBaseFile
{             
  String fn = _basename + T.FileExt;
  
  // ...        
}
[...]

Und warum muss FileExt hier static sein?
Najo Threadstarter
Hält's aus hier
Beiträge: 3



BeitragVerfasst: Sa 25.04.09 12:55 
Ich wollte das Anlegen einer temporären Instanz der der Klasse T vermeiden, also "T.FileExt" schreiben. Ich bin jetzt aber doch dazu über gegangen ein temp. Objekt anzulegen. Ist zwar nicht schön, aber geht, wenn ich das "static" weglasse und "(new T()).FileExt" verwendet.

Viele Grüße und danke für die Antworten
Najo
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Sa 25.04.09 13:21 
Ich würde eher verschiedene Singletons anbieten, siehe z.B. System.Text.Encoding: Über statische Properties wie UTF8 kommst du an ein bestimmtes Encoding-Singleton.

_________________
>λ=