Check inside method whether some optional argument was passed

前端 未结 10 1539
眼角桃花
眼角桃花 2020-11-30 14:00

How do I check if an optional argument was passed to a method?

public void ExampleMethod(int required, string optionalstr = \"default string\",
    int optio         


        
相关标签:
10条回答
  • 2020-11-30 14:14

    Necromancing an old thread, but thought I'd add something.

    You can use default(int) or new int()

    For certain cases the default values can be used to check where an argument was passed. This works for multiple datatypes. 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;
    }
    

    This works particularly well when passing database ids where records hold unsigned integers greater than 0. So you know 0 will always be null and no ids can be negative. In other words, everything other than default(datatype) will be accepted as a passed parameter.


    I would personally go with overloading methods, but another approach (which is perhaps outside the scope of this question) is to make the input parameters into a model. Then use the model force boundaries (like 10 being default parameter), which lets the model deal with the parameter, instead of the method.

    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
        }
    }
    

    This forces behavior before it reaches your method.

    Hope this helps someone.

    0 讨论(0)
  • 2020-11-30 14:18

    You can't, basically. The IL generated for these calls is exactly the same:

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

    The defaulting is performed at the call site, by the compiler.

    If you really want both of those calls to be valid but distinguishable, you can just use overloading:

    // 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
    }
    
    0 讨论(0)
  • 2020-11-30 14:18

    Use nullable is a good solution.. see example below

    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);
    }
    
    0 讨论(0)
  • 2020-11-30 14:20

    You can't check that, because method with optional parameters is a regular method with all parameters, including those which have default values. So, your method will be compiled into:

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

    Default values are inserted by compiler in the call point. If you'll write

    ExampleMethod(42);
    

    Then compiler will generate call

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

    You can compare if optionalstr or optionalint has value equal to default value, but you can't really say if it was provided by compiler or by developer.

    0 讨论(0)
  • 2020-11-30 14:22

    Another approach is to use Nullable<T>.HasValue (MSDN definitions, MSDN examples):

    int default_optionalint = 0;
    
    public void ExampleMethod(int required, int? optionalint,
                                string optionalstr = "default string")
    {
        int _optionalint = optionalint ?? default_optionalint;
    }
    
    0 讨论(0)
  • 2020-11-30 14:28

    You can't do this in C#.

    However, you could overload the function to take differing arguments. That, by the way, is the only approach you can take in Java so you'd be in good company if you adopt it.

    0 讨论(0)
提交回复
热议问题