标题有点古怪,但这就是问题所在。我正在使用C#。我正在尝试提出几种DateTime扩展方法。在考虑它时,我想知道编写如下代码将需要什么样的语法:

DateTime comparisonDate = DateTime.Now.AddMonths(-3);

if( DateTime.Now.IsWithIn(3).Of(comparisonDate) ) ....


我之前已经编写了扩展方法,但是不确定如何编写这样的东西。 “ IsWithIn”将是一个方法...但是这将返回一个Expression,而“ Of”方法将是Expression类的扩展方法吗?

编辑1

还在考虑这个。我想知道这种方法(虽然可读)是否会使事情复杂化。我的第一个修订只是对@Wai Ha Lee进行了调整,它是对DateTimeExtensions类的。我将重构它并继续迭代。这种尖叫策略模式,但我还没有适应它。现在也没有“ Of”方法,而且该方法的名称似乎有意义……至少在今天。从现在开始一个月?我不确定。

我还想到了我希望能够编写此代码的另一种方式。我想我仍在做梦,但是在这里:

date.IsWithIn(1).Days().Of(comparisonDate);
date.IsWithIn(1).Months().Of(comparisonDate);
date.IsWithIn(1).Years().Of(comparisonDate);


除此之外,这是我所拥有的修订版,只是没有方法名称链接的DateTime扩展。

public class Program
{
    static void Main(string[] args)
    {
        DateTime now = DateTime.Now;
        DateTime past = new DateTime(2015, 1, 15);
        DateTime future = new DateTime(2015, 3, 15);
        DateTime comparison = now.AddDays(-2);
        int interval = 1;
        DateInterval di = DateInterval.Days;

        Console.WriteLine(
            string.Format("Now, {0}, is with in {1} {2} of {3} is {4}",
                now.ToShortDateString(),
                interval.ToString(),
                di.ToString(),
                comparison.ToShortDateString(),
                now.IsDateWithinXRangeOfAnotherDate(interval, di, comparison).ToString())
        );

        Console.ReadLine();
    }
}

  public enum DateInterval
    {
        Days,
        Months,
        Years
    }

public static class DateTimeExtensions
{
    public static bool IsDateWithinXRangeOfAnotherDate(this DateTime date, int interval, DateInterval dateInterval, DateTime comparisonDate)
    {
        DateTime _min = comparisonDate;
        DateTime _max = comparisonDate;

        switch(dateInterval)
        {
            case DateInterval.Days:
                _min = _min.AddDays(-interval);
                _max = _max.AddDays(interval);
                Console.WriteLine(
                    string.Format("Min Date is {0} Max Date is {1}",
                        _min.ToShortDateString(),
                        _max.ToShortDateString()));
                break;
            case DateInterval.Months:
                _min = _min.AddMonths(-interval);
                _max = _max.AddMonths(interval);
                Console.WriteLine(
                    string.Format("Min Date is {0} Max Date is {1}",
                        _min.ToShortDateString(),
                        _max.ToShortDateString()));
                break;
            case DateInterval.Years:
                _min = _min.AddYears(-interval);
                _max = _max.AddYears(interval);
                Console.WriteLine(
                    string.Format("Min Date is {0} Max Date is {1}",
                        _min.ToShortDateString(),
                        _max.ToShortDateString()));
                break;
        }

        return _min <= date && date <= _max;
    }
}


编辑2

正在修改:

date.IsWithIn(1).Days().Of(comparisonDate);
date.IsWithIn(1).Months().Of(comparisonDate);
date.IsWithIn(1).Years().Of(comparisonDate);




date.IsWithIn(1.Days()).Of(comparisonDate);
date.IsWithIn(1.Months()).Of(comparisonDate);
date.IsWithIn(1.Years()).Of(comparisonDate);


在看了一下FluentTime之后,我注意到作者使用了一些我什至不知道的方法和类。首先,他使用了TimeSpan.FromDays方法。他可能重载了+符号,因为在代码的另一点,他只是将时间跨度添加到日期中。考虑到TimeSpans的工作方式,我可能只能实现1.Days()部分……我想这就是我真正需要的。

在我弄清楚之前,将继续进行所有操作。我可以只使用FluentTime库,但是由于该库还需要处理时间,因此对于我需要的它来说是太过分了。我对日期范围比较非常感兴趣。诸如After(),Before(),IsBetween(),IsWithIn之类的方法。我已经实现了前三个。这个问题主要在于回答最后一个问题。

编辑3-解决了!

这个问题已成为代码实践,而不是实用性。最终,乔恩·斯基特(Jon Skeet)关于必须创建自定义类型是正确的。该解决方案细分为以下摘要:

自定义类:FluentDateTime已创建
3种int扩展方法-天,月,年。它们每个都返回FluentDateTime类。
1 DateTime扩展方法-IsWithIn带有FluentDateTime参数

我想强调一点,这是一笔不小的开销……但是,不管怎么说,这是代码。

public class FluentDateTime
    {

        public enum DateInterval
        {
            Days,
            Months,
            Years
        }

        private DateTime _lowDate;
        private DateTime _highDate;
        public DateTime BaseDate { get; set; }
        public DateInterval Interval { get; set; }
        public int Increment { get; set; }


        public bool Of(DateTime dt)
        {
            _lowDate = dt;
            _highDate = dt;

            if(this.Interval == DateInterval.Days)
            {
                _lowDate = _lowDate.AddDays(-this.Increment);
                _highDate = _highDate.AddDays(this.Increment);
            }
            else if (this.Interval == DateInterval.Months)
            {
                _lowDate = _lowDate.AddMonths(-this.Increment);
                _highDate = _highDate.AddMonths(this.Increment);
            }
            else
            {
                _lowDate = _lowDate.AddYears(-this.Increment);
                _highDate = _highDate.AddYears(this.Increment);
            }

            Console.WriteLine(
                string.Format("{0} <= {1} <= {2}", _lowDate.ToShortDateString(), BaseDate.ToShortDateString(), _highDate.ToShortDateString()
                ));

            return (_lowDate < BaseDate && BaseDate < _highDate) || (_lowDate.Equals(BaseDate) || _highDate.Equals(BaseDate) );
        }

    }


// DATETIME扩展

public static FluentDateTime IsWithIn(this DateTime date, FluentDateTime fdtParams)
{
    fdtParams.BaseDate = date;
    return fdtParams;
}


// INT扩展

 public static FluentDateTime Days(this int inc)
        {
            FluentDateTime fdt = new FluentDateTime();
            fdt.Interval = FluentDateTime.DateInterval.Days;
            fdt.Increment = inc;
            return fdt;
        }

        public static FluentDateTime Months(this int inc)
        {
            FluentDateTime fdt = new FluentDateTime();
            fdt.Interval = FluentDateTime.DateInterval.Months;
            fdt.Increment = inc;
            return fdt;
        }

        public static FluentDateTime Years(this int inc)
        {
            FluentDateTime fdt = new FluentDateTime();
            fdt.Interval = FluentDateTime.DateInterval.Years;
            fdt.Increment = inc;
            return fdt;
        }


//测试程序

DateTime testDate1 = new DateTime(2015, 3, 3);
            DateTime testDate2 = new DateTime(2015, 3, 4);
            Console.WriteLine(
                string.Format("{0} is within 5 days of {1}? {2} (should be true)",
                    testDate1.ToShortDateString(), testDate2.ToShortDateString(), testDate1.IsWithIn(5.Days()).Of(testDate2)
                ));

            testDate1 = new DateTime(2015, 3, 1);
            testDate2 = new DateTime(2015, 3, 7);
            Console.WriteLine(
                string.Format("{0} is within 3 days of {1}? {2} (should be false)",
                    testDate1.ToShortDateString(), testDate2.ToShortDateString(), testDate1.IsWithIn(3.Days()).Of(testDate2)
                ));

            testDate1 = new DateTime(2015, 3, 3);
            testDate2 = new DateTime(2015, 4, 1);
            Console.WriteLine(
                 string.Format("{0} is within 1 month of {1}? {2} (should be true)",
                     testDate1.ToShortDateString(), testDate2.ToShortDateString(), testDate1.IsWithIn(1.Months()).Of(testDate2)
                 ));


            testDate1 = new DateTime(2015, 3, 3);
            testDate2 = new DateTime(2015, 6, 1);
            Console.WriteLine(
                string.Format("{0} is within 2 month of {1}? {2} (should be false)",
                    testDate1.ToShortDateString(), testDate2.ToShortDateString(), testDate1.IsWithIn(2.Months()).Of(testDate2)
                ));

最佳答案

IsWithin必须返回某种表示值范围的类型,并记住“中心”和范围大小。现在Of可以是它的扩展方法,也可以很容易地成为普通的实例方法,因为您可以自己编写类型。

请注意,3不清楚是3天,3小时还是其他时间。您应该确定如何指定它。您可以使用TimeSpan而不是仅使用int,也可以使用单独的IsWithinDaysIsWithinHours等方法。

09-10 09:15
查看更多