2017-08-03 9 views
2

LINQは今、戻り値を変換するためのC#で簡潔な方法があるすなわちが別のオブジェクトを変換し、LINQスタイル

var x = SomeMethod().Select(t => new { ... }); 

、エレガント別のコレクションにメソッドによって返されたコレクションを変換することができます仲介変数を導入しない方法のラムダを宣言して呼び出すと動作するようですが、かなり醜いです:

var x = new Func<T, object>(t => { return new { ... }; })(SomeMethod()); 

私が何かを明らかに不足しているか、これは1つが、今日のC#でできる最善であるだろうか?

+0

なぜコードが醜いと思いますか?私が行う唯一の方法は、 'var'を実際の戻り値の型と入れ替え、オブジェクト型を指定することです(該当する場合)。そうでなければ、それは受け入れ可能なコードだと思います。 – hbulens

+0

[タプル解体](https://docs.microsoft.com/en-us/dotnet/csharp/tuples#deconstruction)は完全に一般的ではありませんが、いくつかのシナリオでは適用可能です。一般的に、私は実際に何か間違っているのを見ていません(気分!)* 2行*のコードではなく、(var x = SomeMethod(); var y = new {x.foo、x.bar、.. }})。行や変数には税金はありません。とにかく、カバーの下にある仲介業者を使用していないほど短くはありません。 –

+0

@ JeroenMostert私は完全に同意します。私は知的好奇心からこの質問を主に求めています。 –

答えて

1

あなたは次のようにSelectは、SomeMethodを呼び出した結果から作成された一つの項目の順序にSingle続い適用することができます。

var x = Enumerable.Repeat(SomeMethod(), 1).Select(r => new {...}).Single(); 

あなたはそれを多くを行う場合は、このための一般的な拡張メソッドを作ることができます:

static class MyExtensions { 
    public static TRes Transform<TSrc,TRes>(this TSrc src, Func<TSrc,TRes> selector) { 
     return selector(src); 
    } 
} 

今、構文は非常に簡単になる:

var res = SomeMethod().Transform(x => new { ... }); 
+0

右のように、宣言してラムダを呼び出すよりはるかに良いとは確信していません:) –

+0

@FrançoisBeauneラムダの宣言を避けることができます。つまり、 'Func <...>'は画像の外に残っています。 – dasblinkenlight

+0

私はそれを答えとして置いていると思っていますが、中間の配列を作成し、それを反復してから再び1つの要素に減らすことは、一貫して適用すると非常に醜いです)。そして、可視*中間変数を排除するためのすべてのこと! –

0

私はちょうど一般的な拡張メソッドは、ギャップを埋めることができることを考え出し:

public static class TransformExtension 
{ 
    public static T2 Transform<T1, T2>(this T1 t1, Func<T1, T2> transform) 
    { 
     return transform(t1); 
    } 
} 

使用例:それはおそらくひどいアイデアだ理由を聞いてハッピー

public class A { }; 
public class B { }; 

void Foo() 
{ 
    var a = new A(); 
    var b = a.Transform(x => new B()); 
} 

を。

+1

あなたは 'T1'と' T2'をクラスに制限する必要はありません(私の最後の編集を見てください)。 – dasblinkenlight

+0

@dasblinkenlightああ、あなたの編集を見たことがなかった、私はこのソリューションを独自に思いついた...制約に関する良い点、私はそれらを削除します。それは公正なので私はあなたのソリューションを受け入れます:) –

関連する問題