Can I retrieve default value of parameter in method?

Viewed 185

Example:

public static double ComputeFoo(double nom, double den, double epsilon = 2.2e-16)
{
    double den1 = den == 0.0 ? epsilon : den;
    // den1 can still be zero if epsilon is zero
    // is there any way to retrieve 2.2e-16 here and assign it to den1?
    return nom/den1;
}

Is there a way to retrieve 2.2e-16 value and use it in method?

P.S.: I understand that for this particular example I can just call ComputeFoo(nom, den1).

5 Answers

You can set a constant value somewhere in your class, and pass it as the default value to the method. Once there you can check if the passed value is different from the constant or viceversa:

static void Main(string[] args)
{
     Test(0);
}

const int constantValue = 15;

static int Test(int testValue = constantValue)
{
    Console.WriteLine(testValue);
    Console.WriteLine(constantValue);

    return constantValue;
}

Note: constantValue must be a constant in order to build successfuly.

Here's a different approach I mentioned above in my comment using Reflection; generic approach.

public static T GetDefaultOptionalParamValue<T, TClass>(string methodName, string paramName)
{
   if (typeof(TClass).GetMethod(methodName)?.GetParameters().Where(p => p.Attributes.HasFlag(ParameterAttributes.Optional) && 
       p.Attributes.HasFlag(ParameterAttributes.HasDefault) && p.Name == paramName)?.FirstOrDefault()?.DefaultValue is T myValue)
   {
      return myValue;
   }
      else { return default; }
}

You can this call it like so:

 var t = GetDefaultOptionalParamValue<double, ClassName>("ComputeFoo", "epsilon");

t value is 2.2E-16

It's not possible to get the default value just from the method. A way this might work for you is making the default value a constant in your class. For example:

private const double epsilonDefault = 2.2e-16;

public static double ComputeFoo(double nom, double den, double epsilon = epsilonDefault)
{
    double den1 = den == 0.0 ? epsilon : den;
    if (den1 == 0) den1 = epsilonDefault;
    return nom / den1;
}

This way your default value is declared outside the method and available when you need it.

EDIT: To be complete, through reflection it is possible to do this but this seems too much for this question. An basic example of how to do this with reflection:

public static void Execute(int number = 10)
{
    Console.WriteLine(number);
    var defaultValue = typeof(Program)
            .GetMethod("Execute")
            .GetParameters()[0]
            .DefaultValue;
    Console.WriteLine(defaultValue); // 10
}

Use reflection in System.Diagnostics to get access to the parameters. This will get the default value of the third parameter of the enclosing function:

var x = new StackFrame(0).GetMethod().GetParameters()[2].DefaultValue;

NO, you can't. The only default value that can be set is null

public static double ComputeFoo(double nom, double den, double ?epsilon )
{
    if (epsilon == null)
        epsilon = 2.2e-16

    double den1 = den == 0.0 ? epsilon : den;
    // den1 can still be zero if epsilon is zero
    // is there any way to retrieve 2.2e-16 here and assign it to den1?
    return nom/den1;
}
Related