Autor Beitrag
danielf
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Fr 01.06.12 09:54 
Hallo,

ich habe ein Objekt welches verschiedene Interfaces implementiert. Für jedes Interface möchte ich nun gerne eine Methode aufrufen. Wie realisiere ich das?

Ich dachte irgendwie das ich es mit einem Visitor-Pattern realisieren kann ... daran bin ich aber gescheitert (ruft ja nur eine spezifische Methode für ein Objekt auf).

Zum Beispiel:
ausblenden volle Höhe 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:
// interfaces
interface IHasColor { string Color { get; } };
interface IHasSize { int Size { get; } } ;

// Objects
class SingleObject : IHasColor
{
   public string Color { get { return "Blue"; } }
}

class MultipleObject : IHasColor, IHasSize
{
   public string Color { get { return "Red"; } }
   public int Size { get { return 2; } }
}

... Serialize ..
{
   SingleObject single = new SingleObject();
   MultipleObject multiple = new MultipleObject();

   Serialize(single);  // Prints: Color=Blue

   Serialize(multipleObject); // compiler error ambiguous ... Target: Color=Blue\r\nSize=2
}

... Serialize( IHasColor color )
{
   return "Color=" + color.Color;
}

... Serialize( IHasSize size)
{
   return "Size=" + size.Size.ToString();
}


Aus Performance-Gründen würde ich mir gern ein 'is' ersparen.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
string Serialize(object obj)
{
  StringBuilder sb = new StringBuilder();
  if (obj is IHasColor)
  {
     sb.AppendLine(Serialize((IHasColor) obj));
  }

  if (obj is IHasSize)
  {
     sb.AppendLine(Serialize((IHasSize) obj));
  }
}


Danke und Gruß
Daniel
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 01.06.12 11:48 
Wieso implementiert nicht jede Klasse einfach auch ein ISerialize und serialisiert sich selbst? In der Implementierung dieses Interfaces kannst du wieder auf deine wahrscheinlich schon vorhandenen Serialize Methoden umlenken.
danielf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Fr 01.06.12 12:00 
Danke für die Anwort.

Weil ich nicht in jeder Klasse die gleichen Attribute wieder und wieder serialisieren will.

Mit Vererbung geht es auch nicht, da die Vererbungshierarchie nicht vorhanden ist.
( A hat Eigenschaften von B und C,
D hat Eigenschaften von F und C )

Dennoch will ich C nur einmal verarbeiten müssen.

Edit:

Eine gemeinsame Basisklasse mit C reicht auch nicht für das C-Attribut. Das Problem würde dann aber wieder auftauchen bei einem Element G.

A : B, C
D : F, C
G : B, F
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Fr 01.06.12 12:15 
Ich habe deinen Einwurf noch nicht ganz durchschaut.

Die Serialize Methode von Klasse A sähe nach meinem Vorschlag zum Beispiel so aus.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
string ISerialize.Serialize()
{
   MeineKlasseMitDenSerializeMethoden.SerializeA(this);
   MeineKlasseMitDenSerializeMethoden.SerializeB(this);
   MeineKlasseMitDenSerializeMethoden.SerializeC(this);
}
danielf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Sa 02.06.12 12:44 
Ich habe nochmal drüber nach gedacht und du hast natürlich recht. So muss ich die Serialisierung natürlich nicht mehrfach schreiben, aber ich muss dennoch die Methoden aufrufen.

Ich suche einen Ansatz bei dem ich dem Objekt nur die gewissen Schnittstellen implementieren muss und er dann abhängig von den Schnittstellen die Serialize-Methoden aufruft.

Bei dem Beispiel würde ich ja einmal IA : IB, IC definieren und nochmals eine Serialize Methode mit IA die dann Serialize IA, IB, IC aufruft.

Das ganze sollte ohne Reflection oder is/Cast gehen (wegen Performance).

Hast du da vielleicht noch einen Ansatz?

Ich hatte ja gehofft, dass ich es irgendwie so machen kann, dass die verschiedenen Interface-Serializer zwei Methoden haben und wenn das Objekt das Interface implementiert er die "richtige" Methode ausführt und wenn nicht er eine leer Methode ausführt die nichts macht (oder einen Default raus schreibt). Deshalb dachte ich auch an ein Visitor-Pattern, weil da ja da ja ohne Casts, switch oder oder man für jedes Interface/Klasse die richtige Methode ausgwählt wird.

Gruß
Daniel
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4708
Erhaltene Danke: 991


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: Sa 02.06.12 17:57 
Zitat:
Hast du da vielleicht noch einen Ansatz?


Nicht wirklich. Bezweifle auch das das was du möchtest erreichbar ist. Wenn du Reflection, is, as, casts und Konsorten wegen der Performance ausschließt hast du im Prinzip jede Möglichkeit ausgeschlossen generischen Code der zur Laufzeit ausgewertet wird zu erstellen. Um schnellen Code zu schreiben bleibt dann nur die Möglichkeit das durch Wissen zur Designzeit zu ersetzen und entsprechend konkreten Code je Klasse zu erzeugen. Nicht zum reinen Vergnügen versucht ja zum Beispiel der XMLSerializer ja dynamisch Assemblies mit dem Serializercode zu erzeugen. Wenn dir das ~zu blöd~, ~zu aufwendig~, ~zu langweilig~ ist je Klasse ein Serialize Interface manuell zu erstellen und entsprechenden Code dafür zu schreiben würde ich eher in die Richtung denken mir für das Serialisieren einen Codegenerator, Custom Tool, Aspekt etc zu schreiben der mir die Arbeit abnimmt.
danielf Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1012
Erhaltene Danke: 24

Windows XP
C#, Visual Studio
BeitragVerfasst: Mo 04.06.12 08:21 
Okay - scheint wohl so :) Hab gehofft es gibt vielleicht ein Pattern das ich da anwenden kann.

Dann werde ich die Serialisierungsmethoden vom Objekt aufrufen.

Danke und Gruß
Daniel