Linq的Join == 两个foreach

时间:2022-04-08 20:54:34

因为实在太懒了,很久没动笔,今天强迫自己写一个小短篇。

之前讨论过用SelectMany代替两重的foreach循环。今天我们看一下Join和foreach的关系。

首先是Join的定义

public static IEnumerable<TResult> Join<TOuter, TInner, TKey, TResult>(
    this IEnumerable<TOuter> outer,
    IEnumerable<TInner> inner,
    Func<TOuter, TKey> outerKeySelector,
    Func<TInner, TKey> innerKeySelector,
    Func<TOuter, TInner, TResult> resultSelector
)

那么我们根据这个方法的定义的写具体的实现如下

        public static IEnumerable<TResult> MyJoin<TOuter, TInner, TKey, TResult>(
    this IEnumerable<TOuter> outer,
    IEnumerable<TInner> inner,
    Func<TOuter, TKey> outerKeySelector,
    Func<TInner, TKey> innerKeySelector,
    Func<TOuter, TInner, TResult> resultSelector
)
        {

            List<TResult> result = new List<TResult>();

            foreach (var o in outer)
            {
                var outerKey = outerKeySelector(o);

                foreach (var i in inner)
                {
                    var innerKey = innerKeySelector(i);

                    if (outerKey.Equals(innerKey))
                    {
                        result.Add(resultSelector(o, i));
                    }
                }
            }

            return result;
        }

使用场景如下,存在两个有关联的表映射的集合对象。期望对两张表中数据做一个SQL中Join的级联效果

            List<Developer> developers = new List<Developer>
            {
                new Developer{ Name = "Leo1" , ProjectID =1 },
                new Developer{ Name = "Leo2" , ProjectID =2 },
                new Developer{ Name = "Leo3" , ProjectID =3 }
            };

            List<Tester> testers = new List<Tester>
            {
                new Tester{ Name = "Echo1" , ProjectID=1},
                new Tester{ Name = "Echo2" , ProjectID=1},
                new Tester{ Name = "Echo3" , ProjectID=2},
                new Tester{ Name = "Echo4" , ProjectID=2},
                new Tester{ Name = "Echo5" , ProjectID=3},
                new Tester{ Name = "Echo6" , ProjectID=3}
            };


            var projects = developers.MyJoin(testers, d => d.ProjectID, t => t.ProjectID, (d, t) => new { d.ProjectID, Developer= d.Name, Tester = t.Name });

            foreach (var p in projects)
            {
                Console.WriteLine(p.ProjectID);
                Console.WriteLine(p.Developer);
                Console.WriteLine(p.Tester);
            }

一个开发配两个个测试,是不是很开心啊,不过这只是个Sample,你们就死心吧……结果如下

Linq的Join == 两个foreach

很简单的小例子,至少Linq to objects层面还是比较简单的。

同时祝愿各位.NET的工程师们能够越来越专业。面对快50岁的Boss说“代码不重要,业务最重要,代码就是10个if else和8个if else的区别”的时候能够不再迷茫,心中有数。不要把优美的C#写成了堆砌if else和switch case的意大利面条。