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

cnd*_*cnd 52 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);
Run Code Online (Sandbox Code Playgroud)

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

It'*_*ie. 85

你需要let:

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

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

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


Kin*_*ing 79

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

  • 使用大写字母T作为局部变量是非常令人困惑的,因为通常你会期望T是泛型类型参数. (37认同)
  • @KingKing,变量名不应该以大写字母开头,除非它们是属性.惯例是使用`T`表示泛型类型,这意味着使用`T`作为变量名会产生使代码更难阅读的效果. (3认同)
  • @MattPeterson还有lambdas中使用的那些?例如,如果你有一个`IEnumerable <string> names`,当你调用`.Select`时,通常会传递`s => s.Trim()`而不是`name => name.Trim()`. (2认同)

Mat*_*ten 14

是的,使用let关键字:

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


usr*_*usr 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;
Run Code Online (Sandbox Code Playgroud)

这转化为:

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

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);
Run Code Online (Sandbox Code Playgroud)

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