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
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].
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)
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
Hey,
vielen Dank 😃
Hab die Lösung von BerndFfm probiert. Klappt wirklich gut.
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.
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.
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)
Vielen Dank 😃
Dass die Funktion auch negative Werte zurückgeben kann...daran habe ich nicht gedacht.
Aber dann ist es klar.