Laden...

Nicht alle Codepfade geben einen Wert zurück

Erstellt von Timmi vor 6 Jahren Letzter Beitrag vor 6 Jahren 3.690 Views
T
Timmi Themenstarter:in
9 Beiträge seit 2018
vor 6 Jahren
Nicht alle Codepfade geben einen Wert zurück

Hallo zusammen,

ich bin noch recht neu in C# und habe folgendes Problem:
Eine Klasse hat eine Eigenschaft string[][] csvText. Mit einer Methode soll ein Suchbegriff in diesem csvText gesucht werden und die Stelle bestimmt werden, an der dieser Suchbegriff auftaucht.

Der Code der Methode sieht so aus:

private int[] Suchen(string suchbegriff)
        {
            for (int i = 0; i < csvText.GetLength(0); i++)
            {
                for (int j = 0; j < csvText.GetLength(1); j++)
                {
                    if (csvText[i][j] == suchbegriff)
                    {
                        return new int[] {i, j};
                    }
                    else
                    {
                        return new int[] {0, 0};
                    }
                }
            }
        }

Leider gibt Visual Studio immer wieder eine Fehlermeldung heraus, dass nicht alle Codepfade einen Wert zurückgeben. (Fehlercode CS0161)

Es gibt hier doch nur zwei Codepfade, oder nicht? Und beide geben etwas zurück.
Das verstehe ich nicht. Könnt ihr mir bitte helfen?

Danke und Gruß
Timmi

D
261 Beiträge seit 2015
vor 6 Jahren

Und was gibt er zurück wenn dein csvText Array leer ist? 😉

Deine Methode überprüft übrigens nur das Element an der Stelle [0][0].

3.003 Beiträge seit 2006
vor 6 Jahren

Es gibt hier doch nur zwei Codepfade, oder nicht? Und beide geben etwas zurück.

Vielleicht solltest du nicht mit dem Compiler über die Anzahl der vorhandenen Codepfade diskutieren, da verlierst du 😉. Kurze Frage: wie lautet der Codepfad für csvText.GetLength(0) == 0 und csv.GetLength(1) == 0?

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

3.825 Beiträge seit 2006
vor 6 Jahren

Hallo Timmi,

Du verlässt wie schon gesagt beim ersten Schleifendurchlauf deine Routine. Du musst erst alle Schleifen durchlaufen wenn nichts gefunden.

Wenn Du im ersten Element findest [0,0] dann kannst Du das nicht unterscheiden von nichts gefunden. In diesem Fall würde ich [-1,-1] zurückgeben.

Könnte also so aussehen :

private int[] Suchen(string suchbegriff)
{
    for (int i = 0; i < csvText.GetLength(0); i++)
    {
        for (int j = 0; j < csvText.GetLength(1); j++)
        {
            if (csvText[i][j] == suchbegriff)
            {
                return new int[] {i, j};
            }
        }
    }
    return new int[] {-1, -1};
}

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

T
Timmi Themenstarter:in
9 Beiträge seit 2018
vor 6 Jahren

Hey,

vielen Dank 😃
Hab die Lösung von BerndFfm probiert. Klappt wirklich gut.

T
Timmi Themenstarter:in
9 Beiträge seit 2018
vor 6 Jahren

Es gibt hier doch nur zwei Codepfade, oder nicht? Und beide geben etwas zurück.

Vielleicht solltest du nicht mit dem Compiler über die Anzahl der vorhandenen Codepfade diskutieren, da verlierst du 😉. Kurze Frage: wie lautet der Codepfad für csvText.GetLength(0) == 0 und csv.GetLength(1) == 0?

LaTino

Dazu hätte ich noch eine Frage: Wenn ich in den Bedingungen ≤ statt < benutze, müssten die beiden Schleifen auch dann einmal durchlaufen, wenn die Länge von csvText 0 wäre. Aber auch dann sagt mir der Compiler bei meiner alten Version, dass nicht alle Codepfade einen Wert zurückgeben.

Ich möchte nicht mit dem Compiler diskutieren 😉
Aber verstehen, wo der Codepfad ist, der keinen Wert zurückgibt. Denn wenn beide Schleifen mindestens einmal durchlaufen, komme ich doch immer entweder in if oder in else an.

1
124 Beiträge seit 2012
vor 6 Jahren

Der Compiler weiß ja nicht was genau getLenght für Werte haben kann.
Es gibt ja durchaus auch Fälle in dennen die Methode -1 zurück gibt.
Dann hast du wieder das Problem, das die Schleife nicht ausgeführt wird.

3.003 Beiträge seit 2006
vor 6 Jahren

Aber verstehen, wo der Codepfad ist, der keinen Wert zurückgibt. Denn wenn beide Schleifen mindestens einmal durchlaufen, komme ich doch immer entweder in if oder in else an.

Das ist etwas, das du weisst. Der Compiler versteht die Signatur von Methoden - was kann rein, was kann rauskommen - aber er weiß nichts über ihre Funktion. Schauen wir uns mal Array.GetLength() an:

Parameter
dimension
Type: System.Int32
Eine nullbasierte Dimension des Array, deren Länge bestimmt werden soll.

Rückgabewert
Type: System.Int32
Eine 32-Bit-Ganzzahl, die die Anzahl der Elemente in der angegebenen Dimension angibt.

Die Methode könnte also negative Werte zurückgeben, wie 123thomas gesagt hat. Man lernt als Programmierer mit der Zeit, den Code auch aus Sicht des Compilers zu sehen und entsprechend defensiv (für alle Eventualitäten, auch die, die gar nicht eintreffen dürften) zu programmieren. In diesem Fall erzwingt der Compiler diese defensive Programmierung zum Glück.

Abschließend noch ein anderes Beispiel:


class Example 
{
    public virtual int GetValue(int input) => Math.Abs(input);
}
//Anwendung analog zu deinem Beispiel mit GetLength.
void int DoSomething()
{
    Example example = GetExample(); //irgendwoher geliefert
    for(int i = 0; i < example.GetValue(j); ++)
        return bedingung ? 0 : 1;
}

So. Stellen wir uns mal kurz vor, der Compiler würde das zulassen nach dem Motto "der Programmierer weiß schon, was er tut".

Und jetzt kommt der Kollege, der für die GetExample()-Methode zuständig ist, auf folgende Idee:


class OtherExample : Example
{
    public override int GetValue(int input) => input;
}

...und dein Code geht den Bach runter. Und deshalb programmiert man für die Signatur einer Methode, nicht für ihre Bedeutung.

LaTino
EDIT: das ist nicht an den Haaren herbeigezogen. Bei uns ist das eine der häufigsten Gründe für fehlschlagende Unit Tests. (Es gibt reichlich Situationen, wo dich der Compiler nicht zwingen kann, defensiv zu programmieren.)

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

T
Timmi Themenstarter:in
9 Beiträge seit 2018
vor 6 Jahren

Vielen Dank 😃

Dass die Funktion auch negative Werte zurückgeben kann...daran habe ich nicht gedacht.
Aber dann ist es klar.