LINQ的两种写法有什么区别吗?

woodyy 2010-11-27 10:26:08
一直很疑惑的两种写法,

两种写法相同效果的例子

SampleData.Books// 查询操作符 from book in SampleData.Books //查询表达式

.Where(book => book.Title == "Funny Stories") where book.Title == "Funny Stories"

.OrderBy(book => book.Title) orderby book.Title

.Select(book => new {book.Title, book.Price}); select new {book.Title, book.Price};


我经常用“查询操作符”,因为我觉得那更接近于c#编程,容易理解。
你们呢?

请问它们两种的区别除了写法不同还有什么区别,效率上有什么不同?
谢谢呀,
...全文
348 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
足境 2013-07-26
  • 打赏
  • 举报
回复
引用 9 楼 sp1234 的回复:
这是因为你写的太简单了。试试经常写一些5、6个数据集合join的表达式,看看哪一种更清晰?! 比说这个方法:
        internal void Render(Scene scene, bool parallel)
        {
            int[] rgb = new int[screenWidth * screenHeight];
            var pixelsQuery = from y in Enumerable.Range(0, screenHeight).AsParallel().WithDegreeOfParallelism(parallel ? 2 : 1)
                              let recenterY = -(y - (screenHeight / 2.0)) / (2.0 * screenHeight)
                              select from x in Enumerable.Range(0, screenWidth)
                                     let recenterX = (x - (screenWidth / 2.0)) / (2.0 * screenWidth)
                                     let point =
                                         Vector.Norm(Vector.Plus(scene.Camera.Forward,
                                                                 Vector.Plus(Vector.Times(recenterX, scene.Camera.Right),
                                                                             Vector.Times(recenterY, scene.Camera.Up))))
                                     let ray = new Ray() { Start = scene.Camera.Pos, Dir = point }
                                     let computeTraceRay = (Func<Func<TraceRayArgs, Color>, Func<TraceRayArgs, Color>>)
                                      (f => traceRayArgs =>
                                       (from isect in
                                            from thing in traceRayArgs.Scene.Things
                                            select thing.Intersect(traceRayArgs.Ray)
                                        where isect != null
                                        orderby isect.Dist
                                        let d = isect.Ray.Dir
                                        let pos = Vector.Plus(Vector.Times(isect.Dist, isect.Ray.Dir), isect.Ray.Start)
                                        let normal = isect.Thing.Normal(pos)
                                        let reflectDir = Vector.Minus(d, Vector.Times(2 * Vector.Dot(normal, d), normal))
                                        let naturalColors =
                                            from light in traceRayArgs.Scene.Lights
                                            let ldis = Vector.Minus(light.Pos, pos)
                                            let livec = Vector.Norm(ldis)
                                            let testRay = new Ray() { Start = pos, Dir = livec }
                                            let testIsects = from inter in
                                                                 from thing in traceRayArgs.Scene.Things
                                                                 select thing.Intersect(testRay)
                                                             where inter != null
                                                             orderby inter.Dist
                                                             select inter
                                            let testIsect = testIsects.FirstOrDefault()
                                            let neatIsect = testIsect == null ? 0 : testIsect.Dist
                                            let isInShadow = !((neatIsect > Vector.Mag(ldis)) || (neatIsect == 0))
                                            where !isInShadow
                                            let illum = Vector.Dot(livec, normal)
                                            let lcolor = illum > 0 ? Color.Times(illum, light.Color) : Color.Make(0, 0, 0)
                                            let specular = Vector.Dot(livec, Vector.Norm(reflectDir))
                                            let scolor = specular > 0
                                                           ? Color.Times(Math.Pow(specular, isect.Thing.Surface.Roughness),
                                                                         light.Color)
                                                           : Color.Make(0, 0, 0)
                                            select Color.Plus(Color.Times(isect.Thing.Surface.Diffuse(pos), lcolor),
                                                              Color.Times(isect.Thing.Surface.Specular(pos), scolor))
                                        let reflectPos = Vector.Plus(pos, Vector.Times(.001, reflectDir))
                                        let reflectColor = traceRayArgs.Depth >= MaxDepth
                                                            ? Color.Make(.5, .5, .5)
                                                            : Color.Times(isect.Thing.Surface.Reflect(reflectPos),
                                                                          f(new TraceRayArgs(new Ray()
                                                                          {
                                                                              Start = reflectPos,
                                                                              Dir = reflectDir
                                                                          },
                                                                                             traceRayArgs.Scene,
                                                                                             traceRayArgs.Depth + 1)))
                                        select naturalColors.Aggregate(reflectColor,
                                                                       (color, natColor) => Color.Plus(color, natColor))
                                       ).DefaultIfEmpty(Color.Background).First())
                                     let traceRay = Y(computeTraceRay)
                                     select new { X = x, Y = y, Color = traceRay(new TraceRayArgs(ray, scene, 0)) };
            int rowsProcessed = 0;
            pixelsQuery.ForAll(row =>
                {
                    foreach (var pixel in row)
                    {
                        rgb[pixel.X + (pixel.Y * screenWidth)] = pixel.Color.ToInt32();
                    }
                    int processed = Interlocked.Increment(ref rowsProcessed);
                    if (processed % rowsPerUpdate == 0 ||
                        processed >= screenHeight) updateImageHandler(rgb);
                });
        }
它就采取了清晰自然的写法。
完全没看懂..............
#blackheart 2010-11-28
  • 打赏
  • 举报
回复
都一样的,我觉得表达式更贴近人的思维
  • 打赏
  • 举报
回复
这是因为你写的太简单了。试试经常写一些5、6个数据集合join的表达式,看看哪一种更清晰?!

比说这个方法:
        internal void Render(Scene scene, bool parallel)
{
int[] rgb = new int[screenWidth * screenHeight];
var pixelsQuery = from y in Enumerable.Range(0, screenHeight).AsParallel().WithDegreeOfParallelism(parallel ? 2 : 1)
let recenterY = -(y - (screenHeight / 2.0)) / (2.0 * screenHeight)
select from x in Enumerable.Range(0, screenWidth)
let recenterX = (x - (screenWidth / 2.0)) / (2.0 * screenWidth)
let point =
Vector.Norm(Vector.Plus(scene.Camera.Forward,
Vector.Plus(Vector.Times(recenterX, scene.Camera.Right),
Vector.Times(recenterY, scene.Camera.Up))))
let ray = new Ray() { Start = scene.Camera.Pos, Dir = point }
let computeTraceRay = (Func<Func<TraceRayArgs, Color>, Func<TraceRayArgs, Color>>)
(f => traceRayArgs =>
(from isect in
from thing in traceRayArgs.Scene.Things
select thing.Intersect(traceRayArgs.Ray)
where isect != null
orderby isect.Dist
let d = isect.Ray.Dir
let pos = Vector.Plus(Vector.Times(isect.Dist, isect.Ray.Dir), isect.Ray.Start)
let normal = isect.Thing.Normal(pos)
let reflectDir = Vector.Minus(d, Vector.Times(2 * Vector.Dot(normal, d), normal))
let naturalColors =
from light in traceRayArgs.Scene.Lights
let ldis = Vector.Minus(light.Pos, pos)
let livec = Vector.Norm(ldis)
let testRay = new Ray() { Start = pos, Dir = livec }
let testIsects = from inter in
from thing in traceRayArgs.Scene.Things
select thing.Intersect(testRay)
where inter != null
orderby inter.Dist
select inter
let testIsect = testIsects.FirstOrDefault()
let neatIsect = testIsect == null ? 0 : testIsect.Dist
let isInShadow = !((neatIsect > Vector.Mag(ldis)) || (neatIsect == 0))
where !isInShadow
let illum = Vector.Dot(livec, normal)
let lcolor = illum > 0 ? Color.Times(illum, light.Color) : Color.Make(0, 0, 0)
let specular = Vector.Dot(livec, Vector.Norm(reflectDir))
let scolor = specular > 0
? Color.Times(Math.Pow(specular, isect.Thing.Surface.Roughness),
light.Color)
: Color.Make(0, 0, 0)
select Color.Plus(Color.Times(isect.Thing.Surface.Diffuse(pos), lcolor),
Color.Times(isect.Thing.Surface.Specular(pos), scolor))
let reflectPos = Vector.Plus(pos, Vector.Times(.001, reflectDir))
let reflectColor = traceRayArgs.Depth >= MaxDepth
? Color.Make(.5, .5, .5)
: Color.Times(isect.Thing.Surface.Reflect(reflectPos),
f(new TraceRayArgs(new Ray()
{
Start = reflectPos,
Dir = reflectDir
},
traceRayArgs.Scene,
traceRayArgs.Depth + 1)))
select naturalColors.Aggregate(reflectColor,
(color, natColor) => Color.Plus(color, natColor))
).DefaultIfEmpty(Color.Background).First())
let traceRay = Y(computeTraceRay)
select new { X = x, Y = y, Color = traceRay(new TraceRayArgs(ray, scene, 0)) };
int rowsProcessed = 0;
pixelsQuery.ForAll(row =>
{
foreach (var pixel in row)
{
rgb[pixel.X + (pixel.Y * screenWidth)] = pixel.Color.ToInt32();
}
int processed = Interlocked.Increment(ref rowsProcessed);
if (processed % rowsPerUpdate == 0 ||
processed >= screenHeight) updateImageHandler(rgb);
});
}

它就采取了清晰自然的写法。
porschev 2010-11-28
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wuyq11 的回复:]
“Lambda 表达式”是一个匿名函数,Lambda 运算符 =>
LINQ
编译器都是一样的认,也没有性能区别
[/Quote]

如梦出现了。。。。
claymore1114 2010-11-28
  • 打赏
  • 举报
回复
两个当然是一样的。
linq的操作符、linq to sql、linq to xml都是 对linq的扩展,你可以自定义Provider。
利用 表达式树 实现自己的功能。
Ny-6000 2010-11-28
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 wwfgu00ing 的回复:]
都一样的
[/Quote]

是的。
q107770540 2010-11-28
  • 打赏
  • 举报
回复
一种是Lambda表达式
一种是标准查询表达式

最后编译成都会转化成相同的SQL语句
wwfgu00ing 2010-11-28
  • 打赏
  • 举报
回复
都一样的
hch126163 2010-11-27
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wuyq11 的回复:]

“Lambda 表达式”是一个匿名函数,Lambda 运算符 =>
LINQ
编译器都是一样的认,也没有性能区别
[/Quote]

+1
wuyq11 2010-11-27
  • 打赏
  • 举报
回复
“Lambda 表达式”是一个匿名函数,Lambda 运算符 =>
LINQ
编译器都是一样的认,也没有性能区别

62,041

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术交流专区
javascript云原生 企业社区
社区管理员
  • ASP.NET
  • .Net开发者社区
  • R小R
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

.NET 社区是一个围绕开源 .NET 的开放、热情、创新、包容的技术社区。社区致力于为广大 .NET 爱好者提供一个良好的知识共享、协同互助的 .NET 技术交流环境。我们尊重不同意见,支持健康理性的辩论和互动,反对歧视和攻击。

希望和大家一起共同营造一个活跃、友好的社区氛围。

试试用AI创作助手写篇文章吧