除了类参数为null以外的C#可选参数? [英] C# optional parameter besides null for class parameter?
问题描述
此问题的最佳解决方案是什么?我正在尝试创建一个具有几个类类型的可选参数的函数,对于这些参数,null是有意义的值,不能用作默认值.就像
What is the best solution to this problem? I'm trying to create a function that has several optional parameters of class types for which null is a meaningful value and cannot be used as a default. As in,
public void DoSomething(Class1 optional1, Class2 optional2, Class3 optional3)
{
if (! WasSpecified(optional1)) { optional1 = defaultForOptional1; }
if (! WasSpecified(optional2)) { optional2 = defaultForOptional2; }
if (! WasSpecified(optional3)) { optional3 = defaultForOptional3; }
// ... do the actual work ...
}
我不能使用 Class1 optional1 = null
,因为null有意义.我不能使用某些占位符类实例 Class1 optional1 = defaultForOptional1
,因为这些可选参数的编译时常数要求我提供了以下选项:
I can't use Class1 optional1 = null
because null is meaningful. I can't use some placeholder class instance Class1 optional1 = defaultForOptional1
because of the compile-time constant requirement for these optional parameters I've come up with the following options:
- 使用所有可能的组合提供重载,这意味着此方法有8个重载.
- 为每个可选参数包括一个布尔型参数,指示是否使用默认值,这会使签名混乱.
外面有没有人为此提出过一些聪明的解决方案?
Has anyone out there come up with some clever solution for this?
谢谢!
编辑:我最终为编写了一个包装器类,因此不必重复重复 Boolean HasFoo
.
edit: I ended up writing a wrapper class for so I didn't have to keep repeating Boolean HasFoo
.
/// <summary>
/// A wrapper for variables indicating whether or not the variable has
/// been set.
/// </summary>
/// <typeparam name="T"></typeparam>
public struct Setable<T>
{
// According to http://msdn.microsoft.com/en-us/library/aa288208%28v=vs.71%29.aspx,
// "[s]tructs cannot contain explicit parameterless constructors" and "[s]truct
// members are automatically initialized to their default values." That's fine,
// since Boolean defaults to false and usually T will be nullable.
/// <summary>
/// Whether or not the variable was set.
/// </summary>
public Boolean IsSet { get; private set; }
/// <summary>
/// The variable value.
/// </summary>
public T Value { get; private set; }
/// <summary>
/// Converts from Setable to T.
/// </summary>
/// <param name="p_setable"></param>
/// <returns></returns>
public static implicit operator T(Setable<T> p_setable)
{
return p_setable.Value;
}
/// <summary>
/// Converts from T to Setable.
/// </summary>
/// <param name="p_tee"></param>
/// <returns></returns>
public static implicit operator Setable<T>(T p_tee)
{
return new Setable<T>
{
IsSet = true
, Value = p_tee
};
}
}
推荐答案
我至少会考虑为该参数创建新类型:
I would at least consider creating a new type for the parameter:
public void DoSomething(DoSomethingOptions options)
... DoSomethingOptions可能看起来像这样:
... where DoSomethingOptions could look like this:
public class DoSomethingOptions
{
private Class1 class1;
public bool HasClass1 { get; private set; }
public Class1 Class1
{
get { return class1; }
set
{
class1 = value;
HasClass1 = true;
}
}
... for other properties ...
}
然后您可以通过以下方式调用它:
Then you can call it with:
DoSomething(new DoSomethingOptions { Class1 = null, Class2 = new Class2() });
您最终不会出现指数级的重载,您仍然可以合理地紧凑地调用它.
You don't end up with an exponential set of overloads, and you can still call it reasonably compactly.
这类似于 Process
使用 ProcessStartInfo
的方法.
这篇关于除了类参数为null以外的C#可选参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!