Wie lassen sich Casts einsparen ?



  • Hey

    angenommen ich habe div. Interfaces (ia, ib, ic) die nicht von einander erben und auch nicht zusammengefasst werden können sowie einige Klassen (cla, clb, clc) die auch ansonsten völlig alleinstehen und für die gleiches gilt wie für die Interfaces.
    Jede Klasse kann eine beliebige Anzahl Interfaces implementieren desweiteren implementieren alle Klassen mind. das Interface "ia".

    Wie könnte ein solcher Code vereinfacht werden ?

    public int Variable = 15;
    public double AndereVariable = 0.25;
    
    public void Funktion(...){
       ia instanz = getInstanz(...);
    
       if(instanz is ib && ((ib)instanz).VariableA < Variable){
          ((ib)instanz).VariableA = Variable;
       }
    
       if(instanz is ic && ((ic)instanz).VariableB < AndereVariable){
          ((ic)instanz).VariableB = AndereVariable;
       }
    
      ... häufige Verwendung von "instanz" mit den Funktionen aus "ia"
    }
    

    bzw. wie liesen sich das casten reduzieren oder hat ggf. wer eine bessere lösung einen besseren ansatz für soetwas?

    mfg,
    Caster1



  • Ich würde die Casts anders durchführen, dann wird es zumindest etwas lesbarer.

    public void Funktion(...){
       ia instanz = getInstanz(...);
    
       ib myibInstance = instanz as ib;
       if(myibInstance != null && myibInstance.VariableA < Variable)
       {
           myibInstance.VariableA = Variable;
       }
    
       ic myicInstance = instanz as ic;
       if(myicInstance != null && myicInstance.VariableB < AndereVariable)
       {
           myicInstance.VariableB = AndereVariable;
       }
    
      ... häufige Verwendung von "instanz" mit den Funktionen aus "ia"
    }
    

    Der nächste Schritt wäre dann, dass man das ganze in einzelne Methoden aufteilt.

    private void CheckIBInstance(ib myInstance)
    {
       if(myInstance != null && myInstance.VariableA < Variable)
          myInstance.VariableA = Variable;
    }
    
    private void CheckICInstance(ic myInstance)
    {
       if(myInstance != null && myInstance.VariableB < AndereVariable)
          myInstance.VariableB = AndereVariable;
    }
    
    public void Funktion(...){
           ia instanz = getInstanz(...);
           this.CheckIBInstance(instanz as ib);
           this.CheckICInstance(instanz as ic);
    
      ... häufige Verwendung von "instanz" mit den Funktionen aus "ia"
    }
    

    In beiden Fällen musst du jeweils nur einmal auf das entsprechende Interface casten.

    Folgendes könnte dir eventuell noch einen besseren Einblick in das Casten geben:
    [FAQ] Casten aber richtig: () / is / as



  • Wieso verwendest du kein Double Dispatch?

    AInterface:

    interface AInterface
    {
    	void dispatch(DispatchHandlerInterface dispatchHandler);
    }
    

    BInterface:

    interface BInterface : AInterface
    {
    	int VariableA
    	{
    		get;
    		set;
    	}
    }
    

    CInterface:

    interface CInterface : AInterface
    {
    	double VariableB
    	{
    		get;
    		set;
    	}
    }
    

    ClassB:

    class ClassB : BInterface
    {
    	public int VariableA
    	{
    		get;
    		set;
    	}
    
    	public void dispatch(DispatchHandlerInterface dispatchHandler)
    	{
    		dispatchHandler.handle(this);
    	}
    }
    

    ClassC:

    class ClassC : CInterface
    {
    	public double VariableB
    	{
    		get;
    		set;
    	}
    
    	public void dispatch(DispatchHandlerInterface dispatchHandler)
    	{
    		dispatchHandler.handle(this);
    	}
    }
    

    DispatchHandler:

    class DispatchHandler : DispatchHandlerInterface
    {
    	public int Variable = 15;
    	public double AndereVariable = 0.25;
    
    	public void handle(BInterface bi)
    	{
    		if (bi.VariableA < Variable)
    		{
    			bi.VariableA = Variable;
    		}
    	}
    
    	public void handle(CInterface ci)
    	{
    		if (ci.VariableB < AndereVariable)
    		{
    			ci.VariableB = AndereVariable;
    		}
    	}
    }
    

    DispatchHandlerInterface:

    interface DispatchHandlerInterface
    {
    	void handle(CInterface ai);
    	void handle(BInterface bi);
    }
    

    Beispiel:

    DispatchHandler dispatchHandler = new DispatchHandler();
    
    AInterface classB = new ClassB();
    AInterface classC = new ClassC();
    
    classB.dispatch(dispatchHandler); // endet in dispatchHandler.handle(BInterface bi)
    classC.dispatch(dispatchHandler); // endet in dispatchHandler.handle(CInterface ci)
    

Log in to reply