有没有办法避免依赖于表达式的linq投影中的重复?

时间:2017-02-17 06:34:20

标签: c# linq

示例程序:

    class Cat
    {
        public bool IsMale { get; set;}
        public int TailLength { get; set; }
        public string Name { get; set; }
        public decimal ClawAttackFrequency { get; set; }
        public List<DateTime> FeedingTimes { get; set; }
    }


    static void Main(string[] args)
    {
        var cats = new List<Cat>();
        var someData = cats
            .Select(x => new
            {
                x.Name,
                x.IsMale,
                LatestFeedingTime = x.FeedingTimes.Max(y => (DateTime?)y)
            })
            .Select(x => new
            {
                x.Name,
                x.IsMale,
                x.LatestFeedingTime,
                WasFedRecently = x.LatestFeedingTime.HasValue && x.LatestFeedingTime.Value >= DateTime.Today.AddDays(-1)
            });
    }

这只是一个玩具程序,除了它说明了我的问题,为了避免必须复制LatestFeedingTime的表达式,我必须做两个投影并复制一堆属性。

替代方案应该是:

    var someData = cats
        .Select(x => new
        {
            x.Name,
            x.IsMale,
            LatestFeedingTime = x.FeedingTimes.Max(y => (DateTime?)y),
            WasFedRecently = (x.FeedingTimes.Max(y => (DateTime?)y)).HasValue && (x.FeedingTimes.Max(y => (DateTime?)y)).Value >= DateTime.Today.AddDays(-1)
        });

但这反过来重复了一个棘手的表达。

有没有办法在c#中充分利用这两个世界。就像一种声明表达式然后在同一个投影中使用两次的方法?

3 个答案:

答案 0 :(得分:1)

我会这样做:

var someData =
    from x in cats
    let LatestFeedingTime = x.FeedingTimes.Max(y => (DateTime?)y)
    select new
    {
        x.Name,
        x.IsMale,
        LatestFeedingTime,
        WasFedRecently =
            LatestFeedingTime.HasValue
            && LatestFeedingTime.Value >= DateTime.Today.AddDays(-1)
    };

它确实消除了代码中的重复,但是它仍然会生成相同的代码。

你甚至可以缩短它:

var someData =
    from x in cats
    let LatestFeedingTime = x.FeedingTimes.Max(y => (DateTime?)y)
    select new
    {
        x.Name,
        x.IsMale,
        LatestFeedingTime,
        WasFedRecently = LatestFeedingTime >= DateTime.Today.AddDays(-1)
    }

答案 1 :(得分:0)

你可以简单地定义一个返回你想要的Build方法

    var someData = cats
        .Select (Cat.BuildData);

在你的

里面
   public static Something BuildData (Cat cat) {

你可以使用任何局部变量......

答案 2 :(得分:0)

只需使用语句lambda,您可以使用本地变量

Exception in thread "main" java.lang.IllegalStateException: Could not find the FeatureManager. For web applications please verify that the TogglzFilter starts up correctly. In other deployment scenarios you will typically have to implement a FeatureManagerProvider as described in the 'Advanced Configuration' chapter of the documentation.
    at com.amdocs.switchlite.core.context.FeatureContext.getFeatureManager(FeatureContext.java:53)
    at com.feature.MyFeature.isActive(MyFeature.java:20)
    at Test.validate(Test.java:22)
    at Test.main(Test.java:12)

但是如果您认为最近因为可能在过去48小时内喂食它而被喂食,我会为您的猫感到遗憾!