在可选参数中设置DateTime的默认值

111

如何在可选参数中设置DateTime的默认值?

public SomeClassInit(Guid docId, DateTime addedOn = DateTime.Now???)
{
    //Init codes here
}

2
这不是重复的问题。在C#中,时间跨度与时间跨度的工作方式不同。在C#中,可以使用DateTimeConstantAttribute来实现此操作,但时间跨度不支持此操作。 - leat
6个回答

170

对于这个问题,有一个变通方法,利用可空类型和 null 是编译时常量的事实。(虽然有点小技巧,但我建议避免使用,除非确实无法避免。)

public void SomeClassInit(Guid docId, DateTime? addedOn = null)
{
    if (!addedOn.HasValue)
        addedOn = DateTime.Now;

    //Init codes here
}

一般而言,我更喜欢其他答案中建议的标准重载方法:
public SomeClassInit(Guid docId)
{
    SomeClassInit(docId, DateTime.Now);
}

public SomeClassInit(Guid docId, DateTime addedOn)
{
    //Init codes here
}

1
我真的不理解为什么可选参数必须是编译时常量。编译器可以轻松地从带有可选参数的方法中创建你编写的这两个方法...我通常更喜欢有一个带有多个可选参数的方法,而不是几个方法,这使得代码更小,因此更容易阅读。 - user276648
9
您可以在此处使用合并函数:addedOn = addedOn ?? DateTime.Now。该函数的作用是,如果 addedOn 为 null,则将其设置为当前日期和时间(DateTime.Now)。 - Zaid Masud
可空类型在代码深处可能会导致转换问题,所以我不是它的粉丝。我对C#越来越失望了。我的意思是,即使VB.net有字面日期,例如:Optional addedOn As DateTime = #12:00:00 PM#。 - Brain2000
2
VS无法编译此代码。相反,我使用了DateTime date = default(DateTime),然后检查date是否等于default(DateTime)。 - Dan Hastings

59

我猜你实际上不想要 addedOn = DateTime.Now,因为这会意味着你永远都拿不到任何结果,因为所有东西都在“现在”之前添加。 :)

可以像这样设置默认的DateTime

public void SomeClassInit(Guid docId, DateTime addedOn = default(DateTime))

更新
如果你处理的是 SQL Server,请不要忘记它不接受默认值(DateTime)为1/1/0001。SQL Server 的最小 DateTime 是 1/1/1753 (解释)。不过,SQL 的 DateTime2 可以接受 1/1/0001。

1
不明白为什么这不被标记为答案,它允许更轻松地处理日期时间,因为datetime?!= datetime。 - Peter
这是正确的答案。 - A Person
我只是要表达其他人已经说过的话,这确实是正确的答案。其他人基本上只是在作弊。 - CyberClaw
我觉得这会返回一个datetime的默认值。如果有人想要当前的datetime呢? - Ankit Veer Singh

29

我会稍微修改LukeH的解决方案,如下:

public void SomeClassInit(Guid docId, DateTime? addedOn = null)
{
    DateTime TargetDateTimeProperty = addedOn ?? DateTime.Now;
}

看起来更短更易读。


它并不更易读,但它允许我访问.Year/.Month字段。 - Zac

7

不要使用可选参数:

public SomeClassInit(Guid docId, DateTime addedOn)
{
    SomeClassInitCore(docId, addedOn);
}

public SomeClassInit(Guid docId)
{
    SomeClassInitCore(docId, null);
}

private SomeClassInitCore(Guid docId, DateTime? addedOn)
{
    // set default value
    if (addedOn.IsNull) addedOn = DateTime.Now;

    //Init codes here
}

6

.NET 4.0拥有可选参数。(谷歌也是你的好朋友,在此。)

编辑(因为Anthony Pegram评论的更正)...

是的,这就是你应该这样做的。

但是,DateTime.Now(静态属性,在该类上)直到运行时才会知道。 因此,您无法将其用作可选值。

.NET 3.5没有...所以你需要像JS Bangs所说的那样去做...

public SomeClassInit(Guid docId) 
{ 
    return SomeClassInit(docId, DateTime.Now);
}

public SomeClassInit(Guid docId, DateTime addedOn = DateTime.Now???) 
{ 
    //Init codes here 
}

甚至包括munificent的答案中的null检查/空值参数。
感谢Anthony。

默认值必须是编译时常量,所以即使在4.0中也不会起作用。 - Anthony Pegram
确认了,安东尼。我会重新编辑我的帖子。干杯。 - Pure.Krome
1
这应该是被接受的答案(TSBTAA)。这是唯一一个明确解释为什么不能使用常规的 DateTime “值”作为可选参数的答案。 - adamency

2

C#在这个意义上没有可选参数。如果您想使addedOn是可选的,您应该编写一个不需要该参数的重载,并将DateTime.Now传递给两个参数的版本。


1
JS Bangs,你确定吗?对于.NET 3.5及以下版本的框架,你是正确的。但是,4.0及以上版本是支持的。 - Pure.Krome
1
@Pure.Krome,可选参数的默认值必须是编译时常量。因此,这是不支持的。(这个答案可以措辞更好,然而。) - Anthony Pegram
1
我也误解了措辞。抱歉,JS。 - Pure.Krome

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接