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

C# 我可以在方法中检索参数的默认值吗?,c#,optional-parameters,C#,Optional Parameters,例如: 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 d

例如:

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值并在方法中使用


附言:我知道对于这个特定的例子,我可以直接调用
ComputeFoo(nom,den1)
不,你不能。唯一可以设置的默认值为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;
}

您可以在类中的某个位置设置一个常量值,并将其作为默认值传递给方法。到达后,您可以检查传递的值是否与常量或相反的值不同a:

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必须是常量才能成功构建。

仅从方法获取默认值是不可能的。这可能对您有用的一种方法是将默认值设置为类中的常量。例如:

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
}

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

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

下面是我在上面的评论中提到的另一种方法,使用的是
反射
;通用方法

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; }
}
public static T GetDefaultOptionalParamValue(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是T myValue)
{
返回myValue;
}
else{return default;}
}
你可以这样称呼它:

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

t
值是
2.2E-16

2.2E-16
存储为常量,并在默认值和任何需要的地方引用它。如果您确实想得到该值,可以通过反射得到,但我建议不要这样做,也不要做@HereticMonkey已经提到的事情。可以得到该默认值,通过反思。反思对我来说太多了,无法完成这项任务。可悲的是,我无法更改方法的签名。嗯,这可能确实有效,但在我看来,这比它的价值更麻烦。这种方法更简单、更干净。@IgorStack此方法不会更改方法的签名。我同意,我只是说,我不同意你的说法。