我可以在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)
?
答案 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#编译器应该只是优化它,但它没有(或语言规范不允许它,不确定)。