Rückgabewert einer Methode im Sonderfall



  • Hallo,

    ich habe ein immer wiederkehrendes "Design"-Problem.

    Angenommen ihr schreibt einen Raytracer. Wie würdet ihr die Methode zum Schnitt einer Kugel mit einem Ray gestalten?
    Es geht speziell darum, was die Methode machen soll, wenn kein Schnittpunkt existiert.

    Vier Vorschläge. Fallen euch Weitere ein?

    class Sphere
    {
    	public Vector3 Intersect(Ray ray)
    	{
    		//...
    
    		//Kein Schnittpunkt:
    		return null;
    	}
    
    	public Vector3 Intersect(Ray ray)
    	{
    		//...
    
    		//Kein Schnittpunkt:
    		throw new NoIntersectionException();
    	}
    
    	public bool TryIntersect(Ray ray, out Vector3 intersectionPoint)
    	{
    		//...
    
    		//kein Schnittpunkt
    		intersectionPoint = new Vector3(); //dummy für out-Parameter
    		return false;
    	}
    
    	public Vector3 Intersect(Ray ray)
    	{
    		//...
    
    		//kein Schnittpunkt
    		return Vector3.Infinity; //In der Vector3-Klasse: public static Vector3 Infinity = new Vector3();
    	}
    }
    

    Die Lösung mit dem speziellen Vector3.Infinity Objekt gefällt mir eigentlich. Die große Frage ist nur, was passiert wenn der Aufrufer unbedacht damit weiter rechnet. Spätestens dann sollte wohl eine Exception fliegen, oder man setzt die X,Y,Z Werte für Vector3.Infinity auf double.PositiveInfinity.
    Alles nicht so das Wahre.



  • Warum gibst du nicht einfach null zurück wenn es keinen Schnittpunkt gibt? Ansonsten ist die TryIntersect Methode meines Erachtens nach noch die schönste, die wird auch gerne in der Standardbibliothek verwendet (z.b. Int32.TryParse oder beim einem Dictionary TryGetValue).



  • KaPtainCugel schrieb:

    Warum gibst du nicht einfach null zurück wenn es keinen Schnittpunkt gibt?

    Das war ja Möglichkeit 1. Aber imo gilt das als etwas unsauber, null als Sonderfall zu verwenden. Meiner Meinung nach zurecht.


  • Administrator

    Mondlandung schrieb:

    Das war ja Möglichkeit 1. Aber imo gilt das als etwas unsauber, null als Sonderfall zu verwenden. Meiner Meinung nach zurecht.

    Wieso gilt dies als unsauber? Wer sagt das? Notfalls benennst du halt die Methode etwas um: FindIntersection .

    Es kommt halt auch sehr stark auf den Kontext an, in welchem diese Methode aufgerufen wird. Ist es normal, dass mal kein Schnittpunkt gefunden wird? Oder ist es eine Ausnahme, bzw. ein Fehler, dann wäre eine Exception besser.

    Grüssli



  • Mondlandung schrieb:

    Rückgabewert einer Methode im Sonderfall

    Ich denke, daß nicht getroffen wird, ist gar kein Sonderfall, sondern der Normalfall.
    Also keine Exception.

    Wenn Vector3 eh ein Referenztyp ist, ist null doch kostenlos, dann würde ich das nehmen.



  • Ich weiß ja nicht, aber gerade in einem Raytracer würd es ich mir ziemlich stark überlegen, ob Vector3 ein Referenztyp sein sollte...


  • Administrator

    dot schrieb:

    Ich weiß ja nicht, aber gerade in einem Raytracer würd es ich mir ziemlich stark überlegen, ob Vector3 ein Referenztyp sein sollte...

    Ich würde mir zuerst mal ziemlich stark überlegen, einen Raytracer überhaupt in C# zu schreiben 😃

    Grüssli



  • Sagt das mal den Idioten an den Unis, die die Aufgabenstellung schreiben, dass ein Raytracer in Java zu programmieren sein. Weil die heutigen CPUs ja schon fast Raytracing in Echtzeit ermöglichen.

    Und dann auf den Folien: public class Vector4 , Integer und Konsorten (anstelle von int, float, etc.; Integer ist ein Referenztyp 😡), mehrdimensionale Arrays für die Bilddaten (wir brauchen ja 2 Koordinaten, nicht?)...

    C# ist noch heilig.

    *seufz*


Log in to reply