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)ここで2回書き込み/呼び出しをしない方法はありますか?

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 に答える