如何使用 FsCheck 为可为 null 的类型生成 null?

How to generate null for nullable types with FsCheck?

我的这个生成器似乎可以工作,但是当我检查生成的值时,它从不选择空值。如何编写一个将选择空值的生成器。此代码从不为 "end" 日期选择空值。

public static Gen<DateTime?> NullableDateTimeGen()
    {
        var list = new List<DateTime?>();

        if (list.Any() == false)
        {
            var endDate = DateTime.Now.AddDays(5);
            var startDate = DateTime.Now.AddDays(-10);

            list.AddRange(Enumerable.Range(0, 1 + endDate.Subtract(startDate).Days)
                .Select(offset => startDate.AddDays(offset))
                .Cast<DateTime?>()
                .ToList());

            list.Add(null);
            list.Insert(0, null);
        }

        return from i in Gen.Choose(0, list.Count - 1)
               select list[i];
    }

    public static Arbitrary<Tuple<DateRange, DateTime>> TestTuple()
    {
        return (from s in NullableDateTimeGen().Where(x => x != null)
                from e in NullableDateTimeGen()
                from p in NullableDateTimeGen().Where(x => x != null)
                where s <= e
                select new Tuple<DateRange, DateTime>(new DateRange(s.Value, e), p.Value))
                .ToArbitrary();
    }

这个问题与 FsCheck 无关,在这个声明中:

from s in NullableDateTimeGen().Where(x => x != null)
            from e in NullableDateTimeGen()
            from p in NullableDateTimeGen().Where(x => x != null)
            where s <= e
            select new Tuple<DateRange, DateTime>(new DateRange(s.Value, e), p.Value))

请注意,您从 sp 中过滤了空值,因此它们永远不会为空值。如果 e,唯一可以为 null 的东西。然而,你

where s <= e

如果 e 为 null,则此比较永远不会为真,因为与 null 进行比较的任何内容始终为假。因此,您也过滤掉 e 的空值。

要解决这个问题,只需将那个条件替换为对您的情况有意义的任何内容,例如

where e == null || s <= e