11

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

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

4 回答 4

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)? 有时这种技巧可能对练习有用或有趣,但应谨慎使用。

于 2013-06-20T21:29:00.063 回答
14

我建议不要这样做,因为我觉得它的风格很差。也就是说,如果您真的想静态地执行此操作,则需要定义十二种不同的扩展方法(每个月名称一个),如下所示:

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...
}
于 2013-06-20T21:31:21.540 回答
8

你可以通过扩展来做到这一点:

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

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

于 2013-06-20T21:29:11.987 回答
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);

有道理?

于 2013-06-20T22:43:14.997 回答