Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Zugriff auf die Methode eines anderen Interfaces erlangen?
Falke2000
myCSharp.de - Member



Dabei seit:
Beiträge: 21
Herkunft: Köln

Themenstarter:

Zugriff auf die Methode eines anderen Interfaces erlangen?

beantworten | zitieren | melden

Hallo Leute,

Ich habe hier ne kleine Zwickmühle die mich stört weil die Lösung einfach unsauber ist.
Zuerst lege ich euch beide Interfaces vor und im Anschluss der Aufruf des Objektes.
Das Objekt wurde vom Interfacen "IComponent" == mit dem ersten Interface definiert -
brauchen tue ich aber in einem Fall die Methode des zweiten Interfaces (Drawable). Meine einzige Lösung war ein cast auf den zweiten Interface-Typ.

Den Code der Klasse welche beide Interfaces implementiert lasse ich weg. Es geht ja nur um die Möglichkeit die Methode des Drawable Interfaces zu erreichen und die Logik dieser Methode.

Hier der Kot:


	interface IComponent
	{
		void Update(Single elapsedTime);
		void Receive(Sender sender, Message message);
		void SetManager(ComponentManager manager);
	}
}

public interface Drawable
	{
		void Draw(RenderTarget target, RenderStates states);
	}


class PlayerGraphicComponent : IComponent, Drawable
	{
       // Innenleben
     }


class ComponentManager
	{
		private const Int16 _MAX_AMOUNT_OF_COMPONENTS_PER_GAMEOBJECT = 5;
		private Int16 _currentSizeOfArray;
		private IComponent[] _components;

		public ComponentManager()
		{
			_components = new IComponent[_MAX_AMOUNT_OF_COMPONENTS_PER_GAMEOBJECT];
		}
                
                // Andere Methoden...

		/// <summary>
		/// Delivers the Draw-Method to a graphicComponent if available.
		/// </summary>
		/// <param name="target"></param>
		/// <param name="states"></param>
		public void Draw(RenderTarget target, RenderStates states)
		{
			Drawable graphicComponent;

			for(int i = 0; i < _currentSizeOfArray; i++)
			{
				if (_components[i] is Drawable)
				{
					graphicComponent = (Drawable)_components[i];
					graphicComponent.Draw(target, states);
				}
			}
		}


Eine andere Möglichkeit wäre es halt in der Add(IComponent component) Methode (hier nicht einsehbar da ausgeblendet) das Object auf "is Drawable" zu prüfen und daraufhin direkt zu auf (Drawable) zu casten. Ist aber genau so hässlich und ich glaube das Downcasten ist eh verpönt.

Welche Herangehensweise könntet ihr vorschlagen? Ich habe zu wenig Erfahrung um mir noch mehr einfallen zu lassen ;)


gruß Charlie
private Nachricht | Beiträge des Benutzers
t0ms3n
myCSharp.de - Member



Dabei seit:
Beiträge: 319

beantworten | zitieren | melden

Hi,

wenn dich das casten stört, dann nutz eben ein zusätzliches Interface.


public interface IDrawableComponent : IComponent, IDrawable
{

}

class PlayerGraphicComponent : IDrawableComponent
{
    // Innenleben
} 

Dein ComponentManager hält dann ein Array von den IDrawableComponent.

Gruß
t0ms3n
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von t0ms3n am .
private Nachricht | Beiträge des Benutzers
jbrand
myCSharp.de - Member

Avatar #avatar-4142.png


Dabei seit:
Beiträge: 30
Herkunft: Ersrode, Nordhessen

beantworten | zitieren | melden

Hallo,

das casten an sich ist schon in Ordnung, allerdings solltest du den Fall berücksichtigen, dass der Cast auch schief gehen kann. Besser wäre also:


graphicComponent = _components[i] as Drawable;
if (graphicComponent != null)
    graphicComponent.Draw(target, states);

Wenn deine Componenten-Objekte allerdings immer von beiden Interafaces ableiten sollen, dann solltest du wie von t0ms3n vorgeschlagen ein neues Interface definieren und deine Componenten davon ableiten.
Viele Grüße

Jens
private Nachricht | Beiträge des Benutzers
Falke2000
myCSharp.de - Member



Dabei seit:
Beiträge: 21
Herkunft: Köln

Themenstarter:

beantworten | zitieren | melden

Hey Leute!

Danke für die Tipps. Leider ist nur eines von den Componenten wirklich "Draw"-fähig bzw. Soll es sein. Daher möchte ich die Interfaces auseinander halten und den anderen nicht unnötig ein weiteres Verhalten aufzwingen was die nicht benötigen. Ich denke ich bleibe daher beim casten und sichere mich mit != ab :)

Danke !
private Nachricht | Beiträge des Benutzers
pinki
myCSharp.de - Member

Avatar #avatar-4072.jpg


Dabei seit:
Beiträge: 695
Herkunft: OWL

beantworten | zitieren | melden

Hallo,
mir fällt da noch folgendes ein:


foreach (Drawable d in _components.OfType<Drawable>()) {
        d.Draw(target, states);
}
private Nachricht | Beiträge des Benutzers
Falke2000
myCSharp.de - Member



Dabei seit:
Beiträge: 21
Herkunft: Köln

Themenstarter:

beantworten | zitieren | melden

sieht netter aus aber isses auch performanter? Nicht, dass das jetzt arg wichtig wäre - rein interessehalber.

Soweit ich weiss for > foreach (in performance)
private Nachricht | Beiträge des Benutzers
t0ms3n
myCSharp.de - Member



Dabei seit:
Beiträge: 319

beantworten | zitieren | melden

Es ging nicht um das foreach sondern um das OfType :).

Du kannst natürlich dennoch einen for-Loop verwenden.
private Nachricht | Beiträge des Benutzers
Abt
myCSharp.de - Team

Avatar #avatar-4119.png


Dabei seit:
Beiträge: 15695
Herkunft: BW

beantworten | zitieren | melden

Zitat von Falke2000
Soweit ich weiss for > foreach (in performance)
Pauschal ist das inkorrekt.
private Nachricht | Beiträge des Benutzers
Falke2000
myCSharp.de - Member



Dabei seit:
Beiträge: 21
Herkunft: Köln

Themenstarter:

beantworten | zitieren | melden

Zitat von t0ms3n
Es ging nicht um das foreach sondern um das OfType :).

Ah sorry hab ich überflogen - auch ne nette Weise :D
private Nachricht | Beiträge des Benutzers
Coooder
myCSharp.de - Member



Dabei seit:
Beiträge: 186

beantworten | zitieren | melden

Zitat von Falke2000
Soweit ich weiss for > foreach (in performance)

Ich hatte dazu mal ein paar Testloops geschrieben
Mein Ergebnis war das "for" bei normalen Arrays schneller ist
"foreach" war z.B. bei einer List<> schneller
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Coooder am .
private Nachricht | Beiträge des Benutzers
FZelle
myCSharp.de - Experte



Dabei seit:
Beiträge: 10070

beantworten | zitieren | melden

Noch was, solltet ihr irgendwann mal FxCop ( oder jetzt "Code Analysis" ) benutzen, fällt das

if (_components[i] is Drawable)
                {
                    graphicComponent = (Drawable)_components[i];
                    graphicComponent.Draw(target, states);
                }
Sowieso raus.
MS sieht in

graphicComponent = _components[i] as Drawable;
if (graphicComponent != null)
    graphicComponent.Draw(target, states);
Den richtigen weg.
private Nachricht | Beiträge des Benutzers
Falke2000
myCSharp.de - Member



Dabei seit:
Beiträge: 21
Herkunft: Köln

Themenstarter:

beantworten | zitieren | melden

Danke nochmal !
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Falke2000 am .
private Nachricht | Beiträge des Benutzers