Laden...

Was soll eine "void-lose" Methode zurückgeben, wenn sie zu keinem Ergebnis kommt?

Erstellt von carom vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.755 Views
C
carom Themenstarter:in
90 Beiträge seit 2008
vor 14 Jahren
Was soll eine "void-lose" Methode zurückgeben, wenn sie zu keinem Ergebnis kommt?

Hallo ihr!

Ich stehe gerade vor folgendem Problem:

Ich habe eine Methode, welche den Schnittpunkt zwischen Geraden ausrechnet und ihn per return an den Aufrufer zurückliefert, also "return new point(x,y);".
Es kann natürlich sein, dass auch garkein Schnittpunkt existiert. Die Abfrage dafür ist in der Methode schon implementiert, nur weiß ich nicht, was ich jetzt zurückliefern soll.

Was ich mir bisher überlegt habe:

  • return null, geht leider nicht (ich meine, dass es in Java gehen würde) *Return new point("festgelegte Konstanten, auf welche der Aufrufer prüfen muss") ist mir zu unsauber. Es könnte ja zufällig passieren, dass ausgerechnet diese Konstanten wirklich den Schnittpunkt darstellen.
  • die Methode doch void machen und per ref/out Parameter einen "Container" übergeben, der Aufrufer muss diesen dann auf Inhalt prüfen. War ne Idee, aber gefällt mir nicht

Dann wäre da eventuell noch die Möglichkeit, eine Exception zu werfen. Aber dann bei jedem Schnittpunkt mit try/catch kommen, ich weiß nicht...

Was meint ihr? Das sind wie gesagt nur meine laienhaften Ideen, eventuell gibts noch eine viel bessere Lösung 😃

Gruß

I
86 Beiträge seit 2006
vor 14 Jahren

Hallo!

Lass die Methode einen Nullable zurückliefern, also Point? anstatt Point 😉

Lg

C
carom Themenstarter:in
90 Beiträge seit 2008
vor 14 Jahren

Vielen Dank, das kannte ich bisher nicht, aber das sieht spitze aus.

0
767 Beiträge seit 2005
vor 14 Jahren

Du kannst auch eine zweite Methode machen, die nur angibt, OB es einen Schnittpunkt gibt... bzw die die Anzahl von Schnittpunkten zurückgibt (falls du es mal auf allgemeinere Kurven erweiterst)

loop:
btst #6,$bfe001
bne.s loop
rts

C
carom Themenstarter:in
90 Beiträge seit 2008
vor 14 Jahren

Hallo 0815Coder,

ja, das habe ich mir auch überlegt. Allerdings ist das für Anwendungen, bei denen es auf Geschwindigkeit ankommt, sicher nicht so gut geeignet: denn wenn ich erst prüfe, ob ein Schnittpunkt vorhanden ist, und danach den eigentlichen Schnittpunkt berechne, führe ich ja 2 Berechungen aus, die sich allerdings verdammt arg ähneln und ich eigentlich hätte in einer einzigen erledigen können.

U
1.688 Beiträge seit 2007
vor 14 Jahren

die Methode doch void machen und per ref/out Parameter einen "Container" übergeben

Nicht void, sondern bool für Schnittpunkt existiert oder nicht. Mit out werden dann die Koordinaten zurückgegeben.

Es kann natürlich sein, dass auch garkein Schnittpunkt existiert.

Es gibt immer einen Schnittpunkt, zumindest zweidimensional (was Dein Point nahelegt): z. B. (Double.PositiveInfinity, Double.PositiveInfinity) (wahlweise auch negativ...) 😁

C
carom Themenstarter:in
90 Beiträge seit 2008
vor 14 Jahren

Nicht void, sondern bool für Schnittpunkt existiert oder nicht. Mit out werden dann die Koordinaten zurückgegeben.

Ja, das wäre natürlich die beste Möglichkeit wenn man out benutzen will, stimmt, hab ich nicht genug nachgedacht.

Es gibt immer einen Schnittpunkt, zumindest zweidimensional (was Dein Point nahelegt): z. B. (Double.PositiveInfinity, Double.PositiveInfinity) (wahlweise auch negativ...) 😄

Hm, und was, wenn die Geraden parallel verlaufen? Dann will ich eigentlich keinen Schnittpunkt haben.
Dein Smiley lässt eine ironische Aussage vermuten, aber ich verstehe diese nicht ^^

Ansonsten denke ich, dass die nullables eine gute Lösung sind.

EDIT:

zu früh gefreut: point.value.X und point.value.Y lassen sich im Nachinein nicht mehr ändern, ich glaube, da fehlt der Accessor. D.h. bei jedem return in der Methode muss ich

point = new Point();
return point = null;

oder

point = new Point(123/456);
return point;

schreiben 😕

925 Beiträge seit 2004
vor 14 Jahren

Es gibt immer einen Schnittpunkt heißt, dass sich Parallelen im Unendlichen schneiden. Darum Double.PositiveInfinity oder Double.NegativeInfinity als Rückgabewert. Oder 'n NaN, geht auch. Am schönsten finde ich persönlich allerdings wirklich die Nullable-Variante. Dann musst du außerhalb unter Umständen nur nach Point casten.

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo carom,

zu früh gefreut: point.value.X und point.value.Y lassen sich im Nachinein nicht mehr ändern, ich glaube, da fehlt der Accessor.

nein, das ist nicht der Grund. Der Grund ist, dass man bei struct-Properties nicht schreibendend auf Komponenten zugreifen kann, sondern immer den struct als ganzes zuweisen muss. Ich würde aber ohnehin von Nullable abraten. Verwende Point als Rückgabetyp und bool als Out-Parameter. Oder - wie von ujr vorgeschlagen - andersherum.

herbivore

M
7 Beiträge seit 2007
vor 14 Jahren

Und warum baust du dir nicht selber ne Point Klasse?

z.B.:


public class PointEx
    {
        #region constructor PointEx

        public PointEx()
        {

        }

        public PointEx(int x, int y)
        {
            X = x;
            Y = y;
        }

        #endregion

        public int X { get; set; }
        public int Y { get; set; }
    }

Dann kannst Du auch null zurück geben.

3.511 Beiträge seit 2005
vor 14 Jahren

@madas:
Dann müsste man aber immer zwischen den Typen wechseln. Also Point = new Point(pointex.x, pointex.y). Sicherlich kann die PointEx Klasse dies mit eigenen Methoden erledigen (wie z.B. GetPoint oder so), würde aber auf die Dauer Performance kosten. Und nebenbei, gibt es ja bessere Wege 😃

So,

ich würde hier ebenfalls zu einem out Konstrukt raten. Was jetzt der direkte Rückgabewert ist, Point oder bool, ist Geschmackssache. Wobei ich als out den bool nehmen würde.

Dann wäre da natürlich noch das angesprochene Exceptions schmeißen. Wenn es dir um Performance geht, vergiss es 😃. Exceptions sind teuer.

"Jedes Ding hat drei Seiten, eine positive, eine negative und eine komische." (Karl Valentin)

S
443 Beiträge seit 2008
vor 14 Jahren

Entspricht die Anforderung nicht dem normalen TryGet-Pattern?

public bool TryGetSchnittpunkt(out Point schnittpunkt)
{
  schnittpunkt = new Point(0, 0);
  // Schnittpunkt berechnen
  // out parameter 'schnittpunkt' neu zuweisen;
  // wenn Schnittpunkt existiert, return true, sonst false
}

Aufruf:

Point schnittpunkt;
if (TryGetSchnittpunkt(out schnittpunkt))
{
  // schnittpunkt sinnvoll befüllt, man kann mit ihm arbeiten
}
else
  // schnittpunkt garnicht ansehen, da was sinnloses drin steht

so wie halt das TryGetValue vom Dictionary<T1, T2>

mbg
Rossegger Robert
mehr fragen mehr wissen

Montag morgen ist die beste Zeit um eine erfolgreiche Woche zu beginnen

0
767 Beiträge seit 2005
vor 14 Jahren

Um nochmal auf die allgemeineren Kurven zu kommen bei denen es mehrere Schnittpunkte geben kann...

Gibt einfach die Liste aller Schnittpunkte zurück, dann weisst du auch ob es welche gibt, nämlich keinen, wenn die Liste leer ist.

Double.PositiveInfinity und Double.NegativeInfinity würde ich bei parellelen aber nicht verwenden - bin zwar kein Mathematiker und weiss nicht wie die es definieren würden, aber: wenn sich zwei Parallelen der Definition nach in der Unendlichkeit schneiden, dann heisst das, dass sie das sowohl in PositiveInfinity als auch NegativeInfinity tun. Wenn aber 2 Punkte einer geraden auf einer anderen liegen heisst das nach meinem Verständnis, dass auch alle anderen Punkte der Geraden auf der anderen Geraden liegen, was aber nicht geht wenn sie nicht ident sind. Weiters hiesse das ja auch, dass 2 parallele Geraden zumindest nach Definition 2 Schnittpunkte haben müssten, wodurch du schon mal eine Liste mit 2 Einträgen als Rückgabewert für 2 parallele Geraden geben müsstest 😃

loop:
btst #6,$bfe001
bne.s loop
rts

C
carom Themenstarter:in
90 Beiträge seit 2008
vor 14 Jahren

Danke nochmal, habe mich für die Version mit out entschieden 😃

Also zum mathematischen Teil - bei meinem Vorhaben haben 2 Parallelen nunmal nirgends einen Schnittpunkt ^^ ich kenne die Axiome und die angesprochene Definition zwar vom Hörensagen, auf eine konkrete und anschauliche zweidimensionale Darstellung hat die aber meiner Meinung nach keine Auswirkungen. Die Unendlichkeit kann ich nicht konkret am Bildschirm darstellen, also gibt es auch keinen Schnittpunkt.

925 Beiträge seit 2004
vor 14 Jahren

Unendlichkeit kann ich nicht konkret am Bildschirm darstellen

Schön wär's. Ein Unendlich-Zöller. 😄

U
1.688 Beiträge seit 2007
vor 14 Jahren

Die Unendlichkeit kann ich nicht konkret am Bildschirm darstellen, also gibt es auch keinen Schnittpunkt.

Nein - aber sie böte die Möglichkeit, mit Double.IsInfinity festzustellen, ob's einen (endlichen) Schnittpunkt gibt. Es war doch eine Lösungsmöglichkeit, einen "Point" zurückzugeben, mit Werten, die niemals als Schnittpunkt vorkommen können.

C
carom Themenstarter:in
90 Beiträge seit 2008
vor 14 Jahren

Oh Mann, jetzt hab ichs auch kapiert, sorry.
Ja, das wäre in der Tat eine Option gewesen und wäre aus logischer Sicht ja sogar korrekt.
Aber ich werde wohl bei der out-Version bleiben.
Viele Wege führen nach Rom, würde ichs jetzt nochmal umbauen, hätte ich wohl die meisten Wege ausprobiert 😃

0
767 Beiträge seit 2005
vor 14 Jahren

Beim Hobby-Programmieren gilt wie so oft "Der Weg ist das Ziel" 😃

loop:
btst #6,$bfe001
bne.s loop
rts