Hallo Welt!
Ich habe da so eine List bestehend aus genau 6 int. Nun möchte ich in Erfahrung bringen, ob da mind. 2 werte ≥ 15 sind.
Da ich die Reihenfolge aber nicht durcheinander bringen will, habe ich mir gedacht, machst du dir noch eine zusätzliche Liste und füllst sie mit der 1. ab. Diese kann ich dann gefahrenlos sortieren und da ich weiss, dass es immer 6 Zahlen sind, muss ich nur schauen ob die 5. ≥ 15 ist und schon weiss ich, was ich wissen will. So weit so gut.
Wenn ich nun aber diese 2. Liste sortiere, zeigt mir der Debugger an, dass auch die 1. Liste sortiert worden ist. Somit stimmen meine Zahlen nicht mehr überein und alles ist für die Katz.
Warum tut der das?!
private List<int> value = new List<int>();
private List<int> kevin = new List<int>();
value = newRoll.RollDiceGen((int)DiceRule.Free);
tb_Strength.Text = value[0].ToString();
tb_Dexterity.Text = value[1].ToString();
tb_Constituition.Text = value[2].ToString();
tb_Intelligence.Text = value[3].ToString();
tb_Wisdom.Text = value[4].ToString();
tb_Charisma.Text = value[5].ToString();
if (cBox_DiceRule.SelectedIndex == (int)DiceRule.Kevin)
{
kevin = value;
kevin.Sort();
if(kevin[4] < 15)
{
KevinRule();
}
else
{
MessageBox.Show("2 values higher or equal 15 achieved!");
}
}
Klassicher Fehler von Referenz- vs. Werte-Typen in .NET
Value Types and Reference Types
Mit
kevin = value;
machst Du nicht anderes, als dass beide Listen auf den gleichen Speicher zeigen und damit natürlich auch inhaltlich völlig identisch sind.
Was Du machen willst ist eine Listen-Kopie, zB mit
kevin = value.ToList();
Im Falle von Listen mit Werte-Typen wie int zeigen beide Listen dann auch wie gewünscht auf verschiedene Referenzen.
- performance is a feature -
Microsoft MVP - @Website - @AzureStuttgart - github.com/BenjaminAbt - Sustainable Code
Für diese Aufgabe ist es übrigens nicht nötig die Liste zu sortieren. Es geht schneller sie zu durchlaufen und zu zählen wie viele Einträge größer als 15 sind.
Moin
du kannst auch einfach LINQ benutzen. Dann schrumpft das ganze zu einem Einzeiler
var count = kevin.where( x => x>=15 ).Count();
Neben LINQ wird vermutlich eine elementare(re) Herangehensweise verlangt:
...
using System.Collections.Generic;
...
namespace Sort_and_Examine_List_via_LINQ
{
class Program
{
static void Main(string[] args)
{
List<int> numbers = new List<int>();
numbers.Add(4);
numbers.Add(0);
numbers.Add(10);
numbers.Add(50);
numbers.Add(1000);
numbers.Add(40);
// LINQ-Query
// int count = numbers.Where(x => x >= 15).Count();
// Console.WriteLine(count);
int zaehler = 0;
foreach (var result in numbers)
{
if (result > 15)
zaehler += 1;
}
Console.WriteLine("Menge an Zahlen grösser als 15 : " + zaehler);
Console.ReadLine();
}
}
}
Goalkicker.com // DNC Magazine for .NET Developers // .NET Blogs zum Folgen
Software is like cathedrals: first we build them, then we pray 😉
Eine weitere Lösung öhne LINQ wäre auch ein FindAll gewesen, was dann innerhalb der List<T> über die Liste per foreach läuft.
Dann bekommst du ebenfalls eine Liste mit der du dann auch per Count die Anzahl der Elemente bekommst.
Ist zwar das gleiche wie von M.L. aber eben schon mit Bordmitteln der List<T> gelöst.
T-Virus
Developer, Developer, Developer, Developer....
99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.
var count = kevin.where( x => x>=15 ).Count();
Oder auch so:
var countDiceRollsGreater14 = diceRolls.Count(diceRoll => diceRoll > 14);
Zum Code selber noch ein paar Worte:
private List<int> value = new List<int>(); //'value' als Variablen-Name besser nicht verwenden, weil es ein C#-Keyword ist. private List<int> kevin = new List<int>(); value = newRoll.RollDiceGen((int)DiceRule.Free); tb_Strength.Text = value[0].ToString(); tb_Dexterity.Text = value[1].ToString(); tb_Constituition.Text = value[2].ToString(); tb_Intelligence.Text = value[3].ToString(); tb_Wisdom.Text = value[4].ToString(); tb_Charisma.Text = value[5].ToString(); if (cBox_DiceRule.SelectedIndex == (int)DiceRule.Kevin) { // DiceRule.Kevin -> Kevin scheint also ein bestimmter Modus zu sein // Die Liste heißt aber auch kevin. Das ist etwas verwirrend. kevin = value; kevin.Sort(); if(kevin[4] < 15) { // Und was macht KevinRule? Ich dachte, das wäre der Modus. KevinRule(); } else { MessageBox.Show("2 values higher or equal 15 achieved!"); } }
Neben LINQ wird vermutlich eine elementare(re) Herangehensweise verlangt
Ja das denke ich auch. Ich frag mich regelmäßig, warum jemand der ganz am Anfang steht und noch nicht weiß was er da überhaupt tut, ein LINQ Statement hingeknallt kriegt und das dann die Hilfe gewesen sein soll.
Neben LINQ wird vermutlich eine elementare(re) Herangehensweise verlangt
Ja das denke ich auch. Ich frag mich regelmäßig, warum jemand der ganz am Anfang steht und noch nicht weiß was er da überhaupt tut, ein LINQ Statement hingeknallt kriegt und das dann die Hilfe gewesen sein soll.
Ich denke, für Anfänger ist es durchaus interessant zu sehen, wie aus einer vermeintlich komplexen Aufgabe ein gut verständlicher Einzeiler wird.
Als Zusatzinfo natürlich jederzeit. Aber das eigentliche Verständnisproblem sollte man nicht ignorieren.
Ich bin froh dass ich ganz "altmodisch" programmieren gelernt habe. Zunächst ohne Objektorientierung, dafür weiß ich was Pointer sind und wie man C-Style Strings richtig handhabt. Da haben einige gestöhnt warum man das noch braucht, aber ich weiß jetzt wenigstens was ich mache.