我不明白我犯了什么錯誤。
我正在計算一些學生的一般平均水平,并從這個平均水平給全班一個概念。
public enum Grade
{
A,
B,
C,
D,
E
}
var overallAverage = fullScore / numberStudents;
Grade generalGrade;
var cases = new Dictionary<Func<decimal,bool>,Grade>
{
{x => overallAverage < 2, generalGrade = Grade.E},
{x => overallAverage < 4, generalGrade = Grade.D},
{x => overallAverage < 6, generalGrade = Grade.C},
{x => overallAverage < 8, generalGrade = Grade.B},
{x => overallAverage < 10, generalGrade = Grade.A}
};
Console.WriteLine($"Overall Average: {overallAverage} - GRADE: {generalGrade}");
當我開始使用 C# 學習時,我決定使用 Dictionary,但是 General Grade 的結果不是預期的。對于任何平均值,一般成績回傳 A。總體平均值正確回傳值。
uj5u.com熱心網友回復:
您將字典宣告Key為lambda : Dictionary<Func<decimal, bool>, Grade>,從技術上講,您可以在Linq的幫助下查詢它:
using System.Linq;
...
// Techincally, it's possible to use the current dictionary...
generalGrade = cases
.Where(pair => pair.Key((decimal)overallAverage))
.Select(pai => pai.Value)
.Min();
但是,這不是一個好習慣:請注意,我們查詢字典,而不是獲取Valueby Key。如果你想使用字典,試試
// Just mapping average to grade
var cases = new Dictionary<int, Grade>() {
{0, Grade.E},
{1, Grade.E},
{2, Grade.E},
{3, Grade.D},
{4, Grade.D},
{5, Grade.C},
{6, Grade.C},
{7, Grade.B},
{8, Grade.B},
{9, Grade.A},
{10, Grade.A},
};
// Typical dictionary usage: having key (truncated average)
// we obtain value - corresponding grade
generalGrade = cases[(int) overallAverage];
在任意邊界的情況下,我投票給List<>or 陣列并查詢:
using System.Linq;
...
IReadOnlyList<(grade : Grade, min : double)> cases =
new List<(grade : Grade, min : double)>() {
(Grade.A, 8), // to have A student must get at least 8 average
(Grade.B, 6), // to have B student must get at least 6 average
(Grade.C, 4),
(Grade.D, 2),
(Grade.E, 0),
};
...
generalGrade = cases
.Where(item => item.min <= overallAverage)
.OrderBy(item => item.grade)
.First()
.grade;
uj5u.com熱心網友回復:
字典建立鍵和值之間的關系,在這種情況下,您將一個函式作為鍵傳遞,并且給每個函式分配一個等級,這很奇怪,這可能不是您想要做的。
如果您真的想使用字典,那么您可能需要:
var cases = new Dictionary<int, Grade>
{
{ 1, generalGrade = Grade.E},
{ 2, generalGrade = Grade.E},
{ 3, generalGrade = Grade.D},
{ 4, generalGrade = Grade.D},
// ... add the rest of the cases
};
Grade generalGrade = cases[(int)overallAverage];
但這根本沒有效率,我也使用了 int,但是如果您想使用小數,那么這不是最佳解決方案。
而是嘗試:
Func<double, Grade> casesResolver = grade =>
{
if (grade <= 2) return Grade.E;
if (grade <= 4) return Grade.D;
// the rest of the cases here...
return Grade.A;
}
// finally
Grade generalGrade = casesResolver(overallAverage);
Console.WriteLine($"Overall Average: {overallAverage} - GRADE: {generalGrade}");
uj5u.com熱心網友回復:
這不起作用,因為字典需要一個鍵型別作為第一個型別引數。這通常是字串或 int 或 enum 型別。函式在這個地方不起作用,因為它不會作為字典查找的一部分進行評估,只會測驗參考相等性。
您可以使用switch 運算式(C# 8.0) 和關系模式(C# 9.0) 來制定這些條件
Grade grade = overallAverage switch {
< 2 => Grade.E,
< 4 => Grade.D
< 6 => Grade.C
< 8 => Grade.B
_ => Grade.A
};
如果您的 C# 版本較舊,請使用一系列 if 陳述句:
Grade grade;
if (overallAverage < 2) { grade = Grade.E; }
else if (overallAverage < 4) { grade = Grade.D; }
else if (overallAverage < 6) { grade = Grade.C; }
else if (overallAverage < 8) { grade = Grade.B; }
else { grade = Grade.A; }
在這兩種解決方案中,您都不必測驗最后一種情況的條件,因為由于已處理了所有其他可能性,因此等級A是唯一可以應用的等級。請注意,當條件匹配時,不再評估后續條件。
仍然可以通過簡單地使用具有平均值和相應等級的陣列來使用基于資料的解決方案
(decimal average, Grade grade)[] limits =
{ (2m, Grade.E), (4m, Grade.D), (6m, Grade.C), (8m, B) };
Grade grade = Grade.A;
foreach (var limit in limits) {
if (overallAverage < limit.average) {
grade = limit.grade;
break;
}
}
在m作為數字后綴表示decimal。
注意使用正確的比較運算子(<或<=)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/392964.html
下一篇:帶反斜杠的字串到字典
