检查inside方法是否传递了一些可选参数

如何检查是否将可选参数传递给方法?

public void ExampleMethod(int required, string optionalstr = "default string", int optionalint = 10) { if (optionalint was passed) return; } 

另一种方法是使用Nullable.HasValue ( MSDN定义 , MSDN示例 ):

 int default_optionalint = 0; public void ExampleMethod(int required, int? optionalint, string optionalstr = "default string") { int _optionalint = optionalint ?? default_optionalint; } 

好吧,争论总是通过。 默认参数值只是确保用户在调用函数时不必显式指定它们。

当编译器看到这样的调用时:

 ExampleMethod(1); 

它默默地将其转换为:

 ExampleMethod(1, "default string", 10); 

因此,确定参数是否在运行时传递在技术上是不可能的。 你最接近的是:

 if (optionalstr == "default string") return; 

但是如果用户明确地这样调用它,则行为相同:

 ExampleMethod(1, "default string"); 

另外,如果你真的想根据是否提供参数而有不同的行为,那就是去掉默认参数并改用过载,如下所示:

 public void ExampleMethod(int required) { // optionalstr and optionalint not provided } public void ExampleMethod(int required, string optionalstr) { // optionalint not provided } public void ExampleMethod(int required, string optionalstr, int optionalint) { // all parameters provided } 

基本上你不能。 为这些调用生成的IL 完全相同

 ExampleMethod(10); ExampleMethod(10, "default string"); ExampleMethod(10, "default string", 10); 

默认是由编译器在调用站点执行的。

如果您确实希望这两个调用都有效但可区分,则可以使用重载:

 // optionalint removed for simplicity - you'd need four overloads rather than two public void ExampleMethod(int required) { ExampleMethodImpl(required, "default string", false); } public void ExampleMethod(int required, string optionalstr) { ExampleMethodImpl(required, optionalstr, true); } private void ExampleMethodImpl(int required, int optionalstr, bool optionalPassed) { // Now optionalPassed will be true when it's been passed by the caller, // and false when we went via the "int-only" overload } 

你不能在C#中做到这一点。

但是,您可以重载函数以使用不同的参数。 顺便说一下,这是你可以采用Java的唯一方法,所以如果你采用它,你就会很好地合作。

您无法检查,因为带有可选参数的方法是包含所有参数的常规方法,包括具有默认值的参数。 因此,您的方法将编译为:

 public void ExampleMethod(int required, string optionalstr, int optionalint) { } 

编译器在调用点中插入默认值。 如果你要写

 ExampleMethod(42); 

然后编译器将生成调用

 ExampleMethod(42, "default string", 10); 

您可以比较optionalstroptionalint值是否等于默认值,但您无法确定它是由编译器还是开发人员提供的。

你不能,所以你需要找到一种不同的方法来检查“可选”参数。 如果未使用该参数,则可以传入null,然后检查

 if (optionalstr != null) { // do something } 

您还可以重载该方法,其中一个采用可选参数,另一个采用不采用可选参数。 此外,您可以将其设置为使得没有可选参数的方法将空值传递给其中一个重载方法。

 public void ExampleMethod(int required) { ExampleMethod(required, null, 0); } public void ExampleMethod(int required, string optionalstr = "default string", int optionalint = 10) { } 

你不能直接检查,但你可以默认值检查它。 例如:

 public void ExampleMethod(int required, string optionalstr = "default string", int optionalint = 10) { if (optionalint == 10) return; } 

要么

 public void ExampleMethod(int required, string optionalstr = "default string", int? optionalint) { if (required.HasValue==false) return; } 

方法2:

您也可以使用覆盖方法:

 public void ExampleMethod(int required, string optionalstr = "default string") { //When this method called, means optionalint was NOT passed } public void ExampleMethod(int required, string optionalstr = "default string", int optionalint) { //When this method called, means optionalint was passed } 

另一种方法是使用Nullable.HasValue ( MSDN定义 , MSDN示例 ):

 int default_optionalint = 0; public void ExampleMethod(int required, int? optionalint, string optionalstr = "default string") { int _optionalint = optionalint ?? default_optionalint; } 

Necromancing一个旧线程,但我想我会添加一些东西。

你可以使用default(int)new int()

对于某些情况 ,默认值可用于检查参数的传递位置。 这适用于多种数据类型。 https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/default-values-table

 public void ExampleMethod(int optionalInt = default(int)) { if (optionalInt == default(int)) //no parameter passed //do something else //parameter was passed return; } 

这在传递数据库ID时特别有效,其中记录包含大于0的无符号整数。因此,您知道0将始终为null,并且任何ID都不能为负。 换句话说,除默认值(数据类型)之外的所有内容都将被接受为传递参数。


我个人会采用重载方法,但另一种方法(可能超出了本问题的范围)是将输入参数转换为模型。 然后使用模型力边界(如10是默认参数),这使模型处理参数,而不是方法

 public class Example { //...other properties private int _optionalInt; public int OptionalInt { get => _optionalInt; set { if (value <= default(int)) throw new ArgumentOutOfRangeException("Value cannot be 0 or less"); else if (value == 10) throw new ArgumentOutOfRangeException("Value cannot be 10"); else _initValue = value; } } public Example(int optionalInt) { OptionalInt = optionalInt; //validation check in constructor } } 

这会在行为到达您的方法之前强制执行。

希望这有助于某人。

使用nullable是一个很好的解决方案..请参阅下面的示例

 public static void ExampleMethod(bool? optionalBool = null) { Console.WriteLine(optionalBool == null ? "Value not passed" : "Value passed"); } public static void Main() { ExampleMethod(); ExampleMethod(true); ExampleMethod(false); } 

确定参数是否已传递给可选参数

  1. 将极不可能的值定义为参数的默认值。
  2. 如果可选参数是引用类型(如String) ,则可以使用null作为默认值,前提是这不是参数的预期值。
  3. 在过程代码中,将参数与默认值进行比较并执行相应的操作。

https://msdn.microsoft.com/en-us/library/849zff9h(v=vs.100).aspx