Laden...

Zugriff auf die Methode eines anderen Interfaces erlangen?

Erstellt von Falke2000 vor 8 Jahren Letzter Beitrag vor 8 Jahren 3.520 Views
F
Falke2000 Themenstarter:in
21 Beiträge seit 2015
vor 8 Jahren
Zugriff auf die Methode eines anderen Interfaces erlangen?

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

T
314 Beiträge seit 2013
vor 8 Jahren

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

30 Beiträge seit 2007
vor 8 Jahren

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

F
Falke2000 Themenstarter:in
21 Beiträge seit 2015
vor 8 Jahren

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 !

709 Beiträge seit 2008
vor 8 Jahren

Hallo,
mir fällt da noch folgendes ein:


foreach (Drawable d in _components.OfType<Drawable>()) {
        d.Draw(target, states);
}

F
Falke2000 Themenstarter:in
21 Beiträge seit 2015
vor 8 Jahren

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

Soweit ich weiss for > foreach (in performance)

T
314 Beiträge seit 2013
vor 8 Jahren

Es ging nicht um das foreach sondern um das OfType 😃.

Du kannst natürlich dennoch einen for-Loop verwenden.

16.807 Beiträge seit 2008
vor 8 Jahren

Soweit ich weiss for > foreach (in performance)

Pauschal ist das inkorrekt.

F
Falke2000 Themenstarter:in
21 Beiträge seit 2015
vor 8 Jahren

Es ging nicht um das foreach sondern um das OfType 😃.

Ah sorry hab ich überflogen - auch ne nette Weise 😄

C
180 Beiträge seit 2011
vor 8 Jahren

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

F
10.010 Beiträge seit 2004
vor 8 Jahren

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.

F
Falke2000 Themenstarter:in
21 Beiträge seit 2015
vor 8 Jahren

Danke nochmal !