C# 小記 - 值為 null 時 throw 例外
3 |
程式寫到一個查詢方法,規格為傳入名稱查詢 Profile 物件,本想寫成 public Profile GetProfile(string name) => Profiles.SingleOrDefault(o => o.Name == name);
,但規格要求 name 參數不可為 null 或空白,查不到 Profile 需拋出例外,故我退回了傳統寫法:
public Profile GetProfile(string name) {
if (string.IsNullOrEmpty(name)) throw new ArgumentException($"name cannot be null");
var profile = Profiles.SingleOrDefault(o => o.Name == name);
if (profile == null) throw new ArgumentException($"Could not find profile for {name}");
return profile;
}
依近年 C# 卯起來發明語法糖的趨勢,直覺有更精簡的寫法,查了一下,真有 - throw Expression。
C# 7 起 (.NET 4.7+,C# 與 .NET 版本對照表),throw new SomeException(...)
也能當成運算式(Expression),串接在 ??、? : 之中,或當成 => 指向的運算式主體(Expression Body)。於是上述程式碼在 C# 7+ 可簡寫成以下形式:
public Profile GetProfile(string name) =>
string.IsNullOrEmpty(name) ? throw new ArgumentException($"name cannot be empty or null") :
Profiles.SingleOrDefault(o => o.Name == name)
?? throw new ArgumentException($"Could not find profile for {name}");
寫段程式驗證:
public class Profile
{
public string Name { get; set; }
public string SomeProp { get; set; }
}
List<Profile> Profiles = new List<Profile> {
new Profile { Name = "Jeffrey" },
new Profile { Name = "darkthread" }
};
public Profile GetProfile(string name) =>
string.IsNullOrEmpty(name) ? throw new ArgumentException($"name cannot be empty or null") :
Profiles.SingleOrDefault(o => o.Name == name)
?? throw new ArgumentException($"Could not find profile for {name}");
void Main()
{
Action<string> test = (name) => {
try
{
var p = GetProfile(name);
Console.WriteLine($"PASS - {p.Name}");
}
catch (Exception ex) {
Console.WriteLine($"ERR - {name} / {ex.Message}");
}
};
test(null);
test(string.Empty);
test("NoSuchProfile");
test("Jeffrey");
}
Comments
# by kk
我比較想要這個 private void aa() { } catch (...) { } catch () { } finally { }
# by Cash
參數檢查的話,這個比較簡單 https://learn.microsoft.com/en-us/dotnet/api/system.argumentnullexception.throwifnull?view=net-7.0
# by Jeffrey
to Cash, 謝謝補充。(C# 10/.NET 6 起可用)