//this works only for value types which TimeSpan is
void Foo(TimeSpan span = new TimeSpan())
{
if (span == new TimeSpan())
span = TimeSpan.FromSeconds(2);
}
其他的回答 对于为什么可选参数不能是动态表达式给出了很好的解释。但是,要重新计算,默认参数的行为类似于编译时常量。这意味着编译器必须能够对它们进行计算并得出一个答案。有些人希望 C # 增加对编译器在遇到常量声明时计算动态表达式的支持ーー这种特性可能与将方法标记为“纯”有关,但这种情况目前还不存在,而且可能永远不会出现。
对这种方法使用 C # 缺省参数的一种替代方法是使用以 XmlReaderSettings为例的模式。在此模式中,定义一个具有无参数构造函数和公开可写属性的类。然后用此类型的对象替换方法中的所有默认选项。甚至可以通过为该对象指定默认的 null来使该对象成为可选的。例如:
public class FooSettings
{
public TimeSpan Span { get; set; } = TimeSpan.FromSeconds(2);
// I imagine that if you had a heavyweight default
// thing you’d want to avoid instantiating it right away
// because the caller might override that parameter. So, be
// lazy! (Or just directly store a factory lambda with Func<IThing>).
Lazy<IThing> thing = new Lazy<IThing>(() => new FatThing());
public IThing Thing
{
get { return thing.Value; }
set { thing = new Lazy<IThing>(() => value); }
}
// Another cool thing about this pattern is that you can
// add additional optional parameters in the future without
// even breaking ABI.
//bool FutureThing { get; set; } = true;
// You can even run very complicated code to populate properties
// if you cannot use a property initialization expression.
//public FooSettings() { }
}
public class Bar
{
public void Foo(FooSettings settings = null)
{
// Allow the caller to use *all* the defaults easily.
settings = settings ?? new FooSettings();
Console.WriteLine(settings.Span);
}
}