如何写出“流利的”日期时间值?

时间:2013-06-20 21:27:05

标签: c# datetime

如何编写允许编译以下代码的C#代码:

var date = 8.September(2013); // Generates a DateTime for the 8th of September 2013

4 个答案:

答案 0 :(得分:17)

您可以使用扩展方法:

public static class MyExtensions
{
    public static DateTime September(this int day, int year)
    {
        return new DateTime(year, 9, day);
    }
}

然而,这通常是不好的做法,我建议不要这样做,特别是对于像这样微不足道的事情new DateTime(2013, 9, 8)真的比8.September(2013)困难得多吗?有时这种技巧可能对练习有用或有趣,但应该谨慎使用。

答案 1 :(得分:14)

我会建议不要这样,因为它让我觉得非常糟糕。也就是说,如果确实想要静态地执行此操作,则需要定义12种不同的扩展方法(每个月名称一个),如下所示:

public static class DateConstructionExtensions
{
    public static DateTime January(this int day, int year)
    {
        return new DateTime(year, /* month: */1, day);
    }

    // equivalent methods for February, March, etc...
}

答案 2 :(得分:8)

您可以通过扩展程序执行此操作:

public static DateTime September(this int day, int year) {
    return new DateTime(year, 9, day);
}

当然,你需要12个这样的扩展,每个月一个。

答案 3 :(得分:2)

我认为你可以实现这样的实现:

public partial interface IMonth {
    int Number {
        get;
    }
}

public partial class February: IMonth {
    public int Number {
        get {
            return 2;
        }
    }
}

public static partial class Extensions {
    public static DateTime OfMonth<T>(this int day, int year) 
            where T: IMonth, new() {
        var month=new T();
        var daysInMonth=DateTime.DaysInMonth(year, month.Number);

        if(1>day||day>daysInMonth)
            throw new ArgumentException();

        return new DateTime(year, month.Number, day);
    }
}

因为我将月份声明为课程,因为月份可能在不同的文化中有不同的名称。您可能希望为它们提供不同的别名。

然后,由于IMonth的原因,是几个月必须实施的合同。扩展方法具有约束new()用于避免IMonth本身或使用抽象类。

此实现还会检查有效的日期编号。

您可以将变量date指定为:

var date=(28).OfMonth<February>(2013);

有意义吗?