52

我可以在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

4 回答 4

85

你需要let

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

如果您想在查询语法中执行此操作,您可以以更有效(afaik)和更清洁的方式执行此操作:

var q = TypeDescriptor
            .GetProperties(instance)
            .Select(t => t.ComponentType.GetProperty(t.Name))
            .Where(name => name != null);
于 2013-08-05T11:33:39.050 回答
80
var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance)
        let u = t.ComponentType.GetProperty(t.Name)
        where (u != null)
        select u;
于 2013-08-05T11:33:33.203 回答
14

是的,使用let关键字:

var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance)
    let nameProperty = t.ComponentType.GetProperty(t.Name)
    where (nameProperty != null)
    select nameProperty;
于 2013-08-05T11:34:07.957 回答
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# 编译器应该只是优化它,但它没有(或者语言规范不允许它,不确定)。

于 2013-08-16T11:45:19.747 回答