質問
ここでforeach
ループを備えたシンプルな方法です。
IEnumerable<XElement> FieldsToXElements(object instance)
{
var fieldElements = new List<XElement>();
foreach (var field in instance.GetType().GetFields(instance))
{
fieldElements.Add(new XElement(field.Name, field.GetValue(instance)));
}
return fieldElements;
}
醜いの種類。 「何かをする」という意味LINQでいくつかの作業があった場合、それはよりよいなります(例えば、LINQ文で選択されたそれぞれのAction
を実行する)、より簡潔ます:
IEnumerable<XElement> FieldsToXElements(object instance)
{
var fieldElements = new List<XElement>();
from field in instance.GetType().GetFields(instance))
let name = field.Name
let value = field.GetValue(instance)
do fieldElements.Add(new XElement(name, value));
return fieldElements;
}
私はそれは主観的だ実現し、ちょうど私の意見。単にメソッドを呼び出す1行を持つforeachループの場合は、「do
」演算子は、私の意見では、理にかなっています。 MSの誰もが同じことを考えた場合のしかし、私は思ったんだけど。このようLINQ演算子は任意の今後のリリースで計画されている(例えば、C#4.0デビューと一緒に)?の
ここでは、架空の<=>オペレータが実際にコードを見クリーナーになるだろう述語、と、別の例です。これます:
IEnumerable<XElement> FieldsToXElements
(object instance, Func<FieldInfo, bool> predicate)
{
var fieldElements = new List<XElement>();
foreach (var field in instance.GetType().GetFields(instance).Where(predicate))
{
fieldElements.Add(new XElement(field.Name, field.GetValue(instance)));
}
return fieldElements;
}
対。この:
IEnumerable<XElement> FieldsToXElements
(object instance, Func<FieldInfo, bool> predicate)
{
var fieldElements = new List<XElement>();
from field in instance.GetType().GetFields(instance))
let name = field.Name
let value = field.GetValue(instance)
where predicate(field)
do fieldElements.Add(new XElement(name, value));
return fieldElements;
}
解決
いいえ、私は(すなわち、クエリ構文の内側)の直接の言語の対応無しにいつでもすぐに期待しないでください。
それはあなたが神話ForEach
拡張メソッドを意味するように聞こえます。追加するのは簡単、しかしエリックリッペルトは副作用と副作用のない機能コード間のクロスとAction<T>
について何度もコメントしています。具体的には、C#3.0 / .NET 3.5式ツリーは、サイドeffecs(フルラムダサポートがトリッキーする)でお粗末です。ランタイム側は、.NET 4.0 のではるかに優れているが、それは不明です現時点ではどのくらいのこののは、C#4.0で(ラムダコンパイラ)言語にそれを行います。
あなたは(委任バージョンの)必要なのは、次のとおりです。
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{ // note: omitted arg/null checks
foreach(T item in source) { action(item); }
}
そして、あなたは、単に使用することができます任意のクエリから.ForEach(x => /* do something */)
。
他のヒント
あなたの具体的な例(List<XElement>
を移入)については、私はそれをこのようにしてくださいます。
IEnumerable<XElement> FieldsToXElements(object instance)
{
List<XElement> fieldElements =
(
from field in instance.GetType().GetFields(instance))
let name = field.Name
let value = field.GetValue(instance)
select new XElement(name, value)
).ToList(); //Another Option is List<T>.AddRange()
return fieldElements;
}
また:List<T>
はすでに.ForEach<T>()
を実装していることを忘れてはいけないので、任意のEnumerable<T>
に対してそれを使用するためには、これはあなたが必要なすべてのコードです。
myEnumerable.ToList().ForEach( x => myAction(x) );
私は、これはあまりにも難しいですかとは思わない多分私は何かが欠けています...
IEnumerable<XElement> FieldsToXElements(object instance)
{
return instance.GetType()
.GetFields(instance)
.Select( f => new XElement( f.Name,
f.GetValue(instance) ) );
}
、あなたはレッツ割り当て関数への呼び出しを行うことができます。
var qry = from e in somelist
let errorcode = DoSomeProcessing(e)
select e;