Как написать код С#, который позволит скомпилировать следующий код:
var date = 8.September(2013); // Generates a DateTime for the 8th of September 2013
Как написать код С#, который позволит скомпилировать следующий код:
var date = 8.September(2013); // Generates a DateTime for the 8th of September 2013
Вы можете использовать метод расширения:
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)
? Могут быть времена, когда этот трюк может быть полезным или забавным для практики, но его следует использовать экономно.
Я бы рекомендовал против этого, так как это поражает меня как очень плохой стиль. Тем не менее, если вы действительно хотите сделать это статически, вам нужно будет определить двенадцать различных методов расширения (по одному для каждого имени месяца) следующим образом:
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...
}
Вы можете сделать это с помощью расширений:
public static DateTime September(this int day, int year) {
return new DateTime(year, 9, day);
}
Конечно, вам понадобится 12 таких расширений, по одному для каждого месяца.
Я думаю, что вы можете реализовать такую реализацию:
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);
Имеют смысл?