【问题标题】:What should be the default value in a DateTime optional parameter?DateTime 可选参数中的默认值应该是什么?
【发布时间】:2011-12-11 16:16:35
【问题描述】:

通常,如果我有一个可选参数的可空类型,我会将 null 作为默认值。这样我就知道如果值为 null,则调用者不想为该值指定任何值。

public void Foo(string text, string text2= null);

如果参数通常是正整数,我可以使用负数

public void Foo(string text, int index=-1);

日期时间怎么样?它不能为空,并且(据我所知)它没有一个无意义的数字,也不能是真正的输入(如 -1 表示正整数)。或者有吗?在这种情况下你会使用什么?

我也知道我可以使用可为空的DateTime 类型,但这意味着方法调用者必须使用 Nullable,而不是方便地传递 DateTime。

【问题讨论】:

标签: c# .net datetime optional-parameters


【解决方案1】:

您可以使用 C# 中的 ? 运算符使值类型可为空:

DateTime? myDate = null;

由此,您可以将参数设为可选:

void Foo(DateTime? myDate = null)
{
}

Further reading on Nullable Types.

这不是给猫剥皮的唯一方法,您可以使用default(DateTime),但是您不能在可选参数中使用DateTime.MinValueMaxValueNow,因为它们不是编译时常量。

当然,你不需要使用可选参数,如果你想使用 Min、Max 或 Now,你可以使用重载方法。

void Foo()
{
    Foo(DateTime.MinValue);
}

void Foo(DateTime d)
{
}

如果你想大材小用(好吧,也许不是大材小用,有很多正当理由这样做),那么你可以定义一个新的日期类型,它可以理解它何时具有值:

class SmarterDateTime
{
    public bool IsSet { get; set; }

    // Wrapper around DateTime etc excluded.
}

至于什么应该是默认值,如果您愿意,您可以选择将任何日期设为默认值,但对于可选参数之类的内容,您会有限制。

就我个人而言,我倾向于使用DateTime.MinValue

【讨论】:

  • 我知道,但这有点不可取,因为调用者代码也必须使用可空值来调用它
  • @LouisRhys:没有明确表示他们不会 - 存在从 DateTimeDateTime? 的隐式转换。
  • @LouisRhys:ref 参数就是这种情况,或者如果您要获取 DateTime? 值并尝试将其分配给@987654336 @变量。
  • @JonSkeet 这是否意味着如果它只是一个非 ref 参数,调用者根本不会受到影响?
  • @LouisRhys:嗯,它不会是 binary 兼容的更改,还有一些其他极端情况(代表的方法组转换),但对于“正常" 方法调用应该没问题。
【解决方案2】:

默认 (DateTime) - 运算符默认用于它

【讨论】:

  • 它的实际价值是多少?
  • 对于其他想知道的人,实际值为:1-1-0001 0:00:00
  • 相当于DateTime.MinValue(元年正月一日午夜)。
  • 默认(日期时间?)为空
【解决方案3】:

对于“什么可以是 DateTime 的默认值”的问题,回答必须是:您只能使用 default(DateTime)。这是因为默认值必须是const,而DateTime.MinValueDateTime.MaxValue 都只有static readonly,但请注意

default(DateTime) == DateTime.MinValue

下到Kind

如果你愿意,你可以用少一个参数(DateTime)实现一个重载,然后从这个重载调用“main”方法传递你喜欢的值。

但正如别人写的,问题是你写错了前提。

不,日期时间(几乎所有的ValueTypes。几乎都是因为Nullable<Nullable<int>> 是非法的,即使Nullable<T>ValueType可以为空强>。 Nullable<DateTime>DateTime?(相同)

即使int 也可以为空,你知道吗? int? :-)

【讨论】:

    【解决方案4】:

    DateTime.MinValue 将是默认值。

    【讨论】:

      【解决方案5】:

      检查dateTime默认参数,其值为1/1/0001 12:00:00 AM

      private void M(Int32 x = 9, String s = “A”, DateTimedt = default(DateTime), Guidguid = new Guid()) {
      Console.WriteLine(“x={0}, s={1}, dt={2}, guid={3}”, x, s, dt, guid);
      }
      

      【讨论】:

        【解决方案6】:

        如果您使用 Nullable,您的函数的调用者只需将常规 DateTime 传递给它,因此他们不会注意到任何事情 :) 有隐式运算符会为您执行此操作

        如果你想在你的函数中设置一个默认值,你可以这样做:

        public void Foo(DateTime? value = null)
        {
            if ( value == null )
            {
                value = ... // default
            } 
        }
        

        【讨论】:

          【解决方案7】:

          代码片段

          public DateTime method1()
          {
          
            if (condition)
          
              return new DateTime(2007, 5, 30, 11, 32, 00);
          
            else
          
              return default(DateTime);
          
          }
          

          默认语句会将值类型初始化为其默认值。在日期时间的情况下,此值也作为称为 DateTime.MinValue 的静态属性公开。如果使用 C# 1.0,则语句“default(DateTime)”将等效于“DateTime.MinValue”。您可以将此特殊值用作一种“标记”值,这意味着如果返回它,则表示日期时间无效。

          如果再次使用C# 2.0,也可以使用所谓的可空类型,实际上返回NULL,如下例所示

          代码片段

          public DateTime? method2()
          {
          
            if (condition)
          
              return new DateTime(2007, 5, 30, 11, 32, 00);
          
            else
          
              return null;
          
          }
          

          【讨论】:

          • 使用 MVC,我有一个 DateTime 作为可选,但我调用的尝试转换为 datetime 的函数不起作用。添加 ?到函数返回类型完全修复它..谢谢!
          【解决方案8】:
              // This is the best way to null out the DateTime.
              //
              DateTime dateTime2 = DateTime.MinValue;
          

          【讨论】:

          • 这不会“取消”日期时间。它仍然是一个有效值。您如何区分故意指定该值和“不存在”的值?
          【解决方案9】:

          您可以考虑使用值DateTime.MinValue 并使用重载。

          【讨论】:

            【解决方案10】:

            取决于您的用例。

            任何与真实数据不匹配的都可以,但这取决于你对它的使用(所以在某种程度上,-1 对整数来说是这样,因为它是一个非常好的整数,只是因为你使用它只是一个正数整数有意义)。

            如果您要发送一个最小日期(对所有较晚的 foo 感兴趣),那么在最早合理日期之前的任何日期都可以,并且像 .Where(f -> f.When > myDate) 这样的代码将可以工作,甚至无需寻找那个特殊情况。

            同样,最大日期倒数(任何在最新合理日期之后的日期)。

            否则,完全避免使用默认值,而是重载。

            【讨论】:

            • “重载”是指在两个方法中重复方法体吗?
            • 理想情况下,尽可能多的共享是由一个调用另一个共享,或者同时调用一个包含大量代码的私有方法。究竟平衡在哪里取决于您在上述方法中所做的事情。
            • 是的,我同意,但是如果一个调用另一个或两个调用相同的方法,我们仍然要解决原来的问题,不是吗?
            • 只有 if 是这种情况,尽管即使那样它也绕过了签名中的默认值必须是编译时常量这一事实。也有可以调用对方的情况,我们不用去解决,比如IQueryable<Doc> GetDocs(int catID, DateTime published){return GetDocuments(catID).Where(d => d.Published == published);}就完全不用管了。还有DateTime?,您在上面忽略了它,但忽略了可以使用DateTime 参数调用带有DateTime? 参数的方法,因此同样方便。
            猜你喜欢
            • 2011-03-03
            • 1970-01-01
            • 1970-01-01
            • 2015-08-25
            • 1970-01-01
            • 2015-06-19
            • 1970-01-01
            • 2013-10-08
            • 1970-01-01
            相关资源
            最近更新 更多