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

本文关键字:我可以 LINQ 或者 清楚 变量 声明 | 更新日期: 2023-09-27 18:26:37

我可以在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)两次?

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

您需要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);
var q = from PropertyDescriptor t in TypeDescriptor.GetProperties(instance)
        let u = t.ComponentType.GetProperty(t.Name)
        where (u != null)
        select u;

是,使用let关键字:

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

有一个很少有人知道的替代方案(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#编译器应该对此进行优化,但它没有(或者语言规范不允许,不确定)。