0

我写了一个带有可选参数的方法

public void ExampleMethod(int maxValue = 20)
{
  ...
}

我会用它作为

int param = GetSomeValue();
ExampleMethod(param < 20 ? param : use_your_default_value_as_specified);

如果小于 20,则使用参数,否则使用您自己在 ExampleMethod 中实现的默认值(在本例中为 20)。我如何告诉编译器“use_your_default_value_as_specified”?

我知道我可以做到这一点

int param = GetSomeValue();
ExampleMethod(param);

public void ExampleMethod(int maxValue)
{
  if(maxValue > 20)
      maxValue = 20;
}

但我想在执行 ExampleMethod 之前发送正确的值

4

6 回答 6

1

告诉编译器使用参数的默认值的唯一方法是根本不指定它。

您可以使用一些反射 kludgery 在运行时获取值:

public static object DefaultValueForParameter(Type type, string methodName, int parameterNumber)
{
    return type.GetMethod(methodName).GetParameters()[parameterNumber].DefaultValue;
}

ExampleMethod(param < 20 ? param : (int)DefaultValueForParameter(this.GetType(), "ExampleMethod", 0));

但这不是很优雅或高效。

您可以重构ExampleMethod以采用可为空的参数,如下所示:

public void ExampleMethod(int? maxValue = null)
{
    if(maxValue.HasValue)
        maxValue = 20;
}

ExampleMethod(param < 20 ? (int?)param : null);

这样,实际的默认值就隐藏在函数中了。本身,我知道这看起来很像你说你不想使用的代码,有一个关键的区别。它将可以传入的值的逻辑与默认值的逻辑分开。在您声明不想使用的解决方案中,不可能使用 10 作为 a maxValue,因为它会在您的方法中被覆盖。

您还可以重构它,以便默认值是公开可用的常量,如下所示:

const int DefaultMaxValue = 20;

public void ExampleMethod(int? maxValue = DefaultMaxValue)
{
    maxValue.Dump();
}

ExampleMethod(param < 20 ? param : DefaultMaxValue);

通过这种方式,您可以获得一个默认值,您可以在代码中的多个位置使用该默认值,而无需每次都指定它。


不过,如果您不喜欢上述任何解决方案,您可以坚持使用最简单的方法。我知道这不是你要找的东西,但我可能会这样做:

if (param < 20)
    ExampleMethod(param)
else 
    ExampleMethod();

另请注意,如果ExampleMethod返回的不是void,您可以这样做:

var result = param < 20 ? ExampleMethod(param) : ExampleMethod();
于 2013-10-01T21:41:22.523 回答
0

这有点尴尬,但它确实允许您检索默认参数。一旦你有了价值,你可以把它和我上面的答案结合起来,去你想去的地方。

这是 LINQPad 格式。

void Main()
{
    Console.WriteLine(AddEm());

    Console.WriteLine("Default for parm1 is " + GetDefaultParm<int>   (GetType().GetMethod("AddEm"), "parm1"));
    Console.WriteLine("Default for parm2 is " + GetDefaultParm<int>(GetType().GetMethod("AddEm"), "parm2"));
    Console.WriteLine("Default for parm3 is " + GetDefaultParm<int>(GetType().GetMethod("AddEm"), "parm3"));
}

private T GetDefaultParm<T>(MethodInfo m, string parmname) {
    var parm = m.GetParameters().Where(p => p.Name == parmname).FirstOrDefault();
    if (parm != null) {
        return (T) parm.DefaultValue;
    } 
    throw new Exception("Parameter not found.");
}   


// Define other methods and classes here
public int AddEm(int parm1 = 10, int parm2 = 20, int parm3 = 30) {
    return parm1 + parm2 + parm3;
}

输出:

60
Default for parm1 is 10
Default for parm2 is 20
Default for parm3 is 30
于 2013-10-01T22:45:45.713 回答
0

通过您的最后一句话,我假设您希望参数具有您在输入时实际要使用的值ExampleMethod()。您可能会尝试的一件事是创建另一个对象或静态方法来为您计算该值。

class Helper {
    public static int MakeParam(int myParam) {
      return myParam < 20 ? myParam : use_your_default_value_as_specified;
    }
}
...
ExampleMethod(Helper.MakeParam(17));

这允许您对方法外部的参数执行任何逻辑。如果您需要它,您甚至可以拥有一个允许您传入默认值的版本:

class Helper {
    public static int MakeParam(int myParam) {
      return MakeParam(myParam, use_your_default_value_as_specified);
    }
    public static int MakeParam(int myParam, int myDefault) {
      return myParam < 20 ? myParam : myDefault;
    }
}

然后,您可以使用命名参数为您要使用的参数提供值:

void Main()
{
    Console.WriteLine(AddEm(parm3:50)); // = 80
    Console.WriteLine(AddEm(parm2:50)); // = 90
    Console.WriteLine(AddEm());         // = 60)
}

public int AddEm(int parm1 = 10, int parm2 = 20, int parm3 = 30) {
    return parm1 + parm2 + parm3;
}

祝你好运!

于 2013-10-01T21:56:40.060 回答
0

您可以创建一个方法,只进行术语检查并将要使用的正确值分配给 var。(反对默认值)。然后,在检查了 6-7 个变量后,调用该方法并提供这些变量。

于 2013-10-01T21:57:36.477 回答
0

可以上课吗?

// Individual Parameter Values 
class ParameterValueClass { 
   double _Value; 
   double _Max; 
   public double Value { get { return (_Value < _Max) ? _Value : _Max }
                         set  { _Value = value; } } 
   public ParameterValueClass(Max) { _Max = Max; } 
 } 
// Set of Parameter Values 
class ParameterSetClass { 
      public ParameterValueClass Parameter1;
      public ParameterValueClass Parameter2;
      public ParameterValueClass Parameter3;
      public ParameterSetClass () { 
          Parameter1 = new ParameterValueClass(20);
          Parameter2 = new ParameterValueClass(4.22314);
          Parameter3 = new ParameterValueClass(700000);
      }
 } 

void ExampleMethod(ParameterSetClass Parameters) {
    /// Parameter1.Value returns the Value or "Max" value. Could also use a min value. 

  }
于 2013-10-01T21:53:30.457 回答
0

您始终可以使用反射。参数集合中的此示例代码包含具有默认值的参数列表。每个参数都有属性 DefaultValue 及其默认值。

private void Calc(int i, int j, int k = 60, int l = 80)
    {
        var parameters =
            System.Reflection.MethodInfo.GetCurrentMethod().GetParameters().Where(param => param.HasDefaultValue);
      //parameters = {k, l}

    }
于 2013-10-01T21:54:33.630 回答