C#:我可以在方法中检索参数的默认值吗?

问题描述 投票:1回答:5

示例:

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

是否有一种方法可以检索2.2e-16值并在方法中使用它?

P.S .:我了解对于此特定示例,我可以仅致电ComputeFoo(nom, den1)

c# optional-parameters
5个回答
1
投票

您可以在类的某个位置设置一个常量值,并将其作为默认值传递给该方法。在那里,您可以检查所传递的值是否不同于常量,反之亦然:

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

注意:constantValue必须是一个常量才能成功构建。


1
投票

仅从方法中不可能获得默认值。一种可能对您有用的方法是使默认值在您的类中成为常量。例如:

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

这样,您的默认值在方法外部声明,并在需要时可用。

编辑:为了完整起见,可以通过反思来做到这一点,但这对于这个问题来说似乎太过分了。有关如何通过反射执行此操作的基本示例:

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

0
投票

不,你不能。唯一可以设置的默认值为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;
}

0
投票

使用System.Diagnostics中的反射来访问参数。这将获得封闭函数的第三个参数的默认值:

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

0
投票

这是我在上面的评论中使用Reflection提到的另一种方法;通用方法。

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

您可以这样称呼它:

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

[t值为2.2E-16

© www.soinside.com 2019 - 2024. All rights reserved.