[英]how to specify optional anonymous ienumerable parameters in c# abstract method
[英]How can I wrap a method with optional parameters in C#?
我有以下C#類(在此簡化):
internal static class Assertions {
public static void Assert(bool condition, string message = "Assertion failed") {
if (!condition) { throw new System.Exception(message); }
}
public static void NotNull(object o, string message = "Assertion failed") {
Assert(!Object.ReferenceEquals(o, null), message);
}
public static void EtCaetera(..., string message = "Assertion failed") {
Assert(..., message);
}
}
如您所見,我有一個Assertions.Assert()
方法,帶有可選參數string message = "Assertion failed"
。
當我圍繞該方法編寫包裝器時,我希望包裝器具有默認的參數string message
,但是我想避免重復默認值( "Assertion failed"
),因為這違反了DRY原理:如果我想要要將消息"Assertion failed"
更改為"I crashed"
,我將不得不在許多地方更改該默認值。
如何傳遞可選參數的“缺失”? 我正在尋找類似的東西:
public static void NotNull(object o, string message = Type.Missing) {
Assert(!Object.ReferenceEquals(o, null), message);
}
另一個選擇是不使用可選參數,並為每個方法提供兩個版本,但這會很快變得麻煩。
可選參數是在編譯時解析的,不會被替換為特殊值,因此此處沒有太多選項。
如果您不想重復自己的話,我的建議是引入一個特殊值(以模仿Type.Missing
是什么):
internal static class Assertions {
public static void Assert(bool condition, string message = null) {
if (!condition) {
throw new System.Exception(message ?? "Assertion failed");
}
}
}
internal static class Wrapper {
public static void Assert(bool condition, string message = null) {
Assertions.Assert(condition, message);
}
}
這還有另一個(IMO大的)優勢:如果您更改錯誤消息 (或將其本地化 ),則不必更改所有代碼(現有的編譯庫將被更新 )。 不要忘記,在您的原始代碼中,這樣的調用:
Assertions.Assert(value > 0);
將被轉換(和編譯,即使您使用const
字段)為:
Assertions.Assert(value > 0, "Assertion failed");
因此,即使您更改默認消息,編譯后的程序集也不會得到更新。
我更喜歡將null
作為可選參數的默認值。
internal static class Assertions {
private const string DefaultMessage = "Assertion failed";
public static void Assert(bool condition, string message = null) {
message = message ?? DefaultMessage;
if (!condition) { throw new System.Exception(message); }
}
public static void NotNull(object o, string message = null) {
message = message ?? DefaultMessage;
Assert(!Object.ReferenceEquals(o, null), message);
}
public static void EtCaetera(..., string message = null) {
message = message ?? DefaultMessage;
Assert(..., message);
}
}
默認值需要在第一個方法(即包裝器)上指定,因為這是將值應用於參數的位置。 Type.Missing
是一個特殊的值,在COM互操作中具有含義。 您可以嘗試以下一些適合您需求的選項。
在基本方法上使用OptionalAttibute ,並在覆蓋的方法上指定默認值。
class Class2 : Class1 { public override string MethodWithOptParams(string message = "default message") { return base.MethodWithOptParams(message); } } class Class1 { public virtual string MethodWithOptParams([Optional]string message) { return message; } }
將默認值聲明為in,並應用與默認值相同的常量。
class Class2 : Class1 { public override string MethodWithOptParams(string message = DefaultMessage) { return base.MethodWithOptParams(message); } } class Class1 { protected const string DefaultMessage = "default message"; public virtual string MethodWithOptParams(string message = DefaultMessage) { return message; } }
在包裝器中將null用作默認值,並對對基本方法的兩個替代調用進行編碼。
class Class2 : Class1 { public override string MethodWithOptParams(string message = null) { if (message == null) { return base.MethodWithOptParams(); } else { return base.MethodWithOptParams(message); } } } class Class1 { public virtual string MethodWithOptParams(string message = "default message") { return message; } }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.