我可以在LINQ中声明/使用一些变量吗?或者我可以写下LINQ更清楚的吗?

时间:2013-08-05 11:32:14

标签: c# linq

我可以在LINQ中声明/使用某个变量吗?

例如,我可以编写以下LINQ清除程序吗?

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance)
        where (t.ComponentType.GetProperty(t.Name) != null)
        select t.ComponentType.GetProperty(t.Name);

有没有办法不在这里写两次t.ComponentType.GetProperty(t.Name)

4 个答案:

答案 0 :(得分:85)

您需要let

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance)
        let name = t.ComponentType.GetProperty(t.Name)
        where (name != null)
        select name;

如果你想在查询语法中这样做,你可以用更高效(更好)和更清洁的方式来做:

var q = TypeDescriptor
            .GetProperties(instance)
            .Select(t => t.ComponentType.GetProperty(t.Name))
            .Where(name => name != null);

答案 1 :(得分:79)

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance)
        let u = t.ComponentType.GetProperty(t.Name)
        where (u != null)
        select u;

答案 2 :(得分:14)

是的,使用let关键字:

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance)
    let nameProperty = t.ComponentType.GetProperty(t.Name)
    where (nameProperty != null)
    select nameProperty;

答案 3 :(得分:7)

有一个很少人知道的替代方案(select a into b):

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance)
        select t.ComponentType.GetProperty(t.Name) into u
        where u != null
        select u;

这转化为:

var q = TypeDescriptor.GetProperties(instance)
        .Select(t => t.ComponentType.GetProperty(t.Name))
        .Where(prop => prop != null);

而基于let的版本转换为:

var q = TypeDescriptor.GetProperties(instance)
        .Select(t => new { t, prop = t.ComponentType.GetProperty(t.Name) })
        .Where(x => x.prop != null)
        .Select(x => x.prop);

每个项目的不必要分配,因为t仍在范围内(尚未使用)。 C#编译器应该只是优化它,但它没有(或语言规范不允许它,不确定)。