可选参数和默认值
本文关键字:默认值 参数 | 更新日期: 2023-09-27 18:33:27
我写了一个接受可选参数的方法
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;
}
但我想在执行示例方法之前发送正确的值
告诉编译器使用参数的默认值的唯一方法是根本不指定它。
您可以使用一些反射算法在运行时获取值:
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();
这有点尴尬,但它确实允许您检索默认参数。一旦你有了价值,你可以把它和我上面的答案结合起来,到达你想去的地方。
这是 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
你能用一个类吗?
// 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.
}
您始终可以使用反射。参数集合中的此示例代码包含具有默认值的参数列表。每个参数都具有具有默认值的属性默认值。
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}
}
您可以创建一个方法,该方法仅执行术语检查并将要用于的正确值分配给 var.(针对默认值(。然后,在检查 6-7 个变量后,调用该方法并提供这些变量。
通过您的最后一句话,我假设您希望参数具有输入 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;
}
祝你好运!