可选参数和默认值

时间:2013-10-01 21:39:33

标签: c# methods parameters call optional

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

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

我会将其用作

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

如果它小于20,使用param,否则使用你自己在ExampleMethod中实现的默认值(在这个例子中它是20)..我怎么能告诉编译器“use_your_default_value_as_specified”?

我知道我可以通过

来做到这一点
int param = GetSomeValue();
ExampleMethod(param);

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

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

6 个答案:

答案 0 :(得分: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}用作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();

答案 1 :(得分: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. 

  }

答案 2 :(得分: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}

    }

答案 3 :(得分: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;
}
祝你好运!

答案 4 :(得分:0)

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

答案 5 :(得分: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
相关问题