Here's a simple method with a foreach
loop:
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;
}
Kind of ugly. If there were some operator in LINQ that mean "do something" (e.g. perform an Action
for each selected in the LINQ statement), it would look nicer, more terse:
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;
}
I realize that's subjective, and just my opinion. For a foreach loop that has one line that simply invokes a method, a "do
" operator makes sense, in my opinion. But I'm wondering if anyone at MS has thought the same thing. Is such LINQ operator planned in any upcoming releases (e.g. alongside the C# 4.0 debut)?
Here's another example, with a predicate, where the fictitious do
operator would really make the code look cleaner. This:
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;
}
vs. this:
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;
}
First off, if you're starting a new project, use Entity Framework ("EF") instead of Linq to SQL because it now generates far better SQL (more like Linq to SQL does) and is easier to maintain ("L2S").
The Any operator is used to check whether any element in the sequence or collection satisfy the given condition. If one or more element satisfies the given condition, then it will return true. If any element does not satisfy the given condition, then it will return false.
By default, only one thread is used to execute a LINQ query. Parallel LINQ (PLINQ) is an easy way to enable multiple threads to execute a query. To see it in action, we will start with some code that only uses a single thread to double 200 million integers.
LINQ to Entities provides Language-Integrated Query (LINQ) support that enables developers to write queries against the Entity Framework conceptual model using Visual Basic or Visual C#. Queries against the Entity Framework are represented by command tree queries, which execute against the object context.
No, I don't expect any direct language suport (i.e. inside the query syntax) any time soon.
It sounds like you mean the mythical ForEach
extension method; trivial to add, but Eric Lippert has commented numerous times about the cross between side-effect-free functional code and Action<T>
with side-effects. In particular, C# 3.0 / .NET 3.5 expression trees are lousy at side-effecs (making full lambda support tricky). The runtime side is much better in .NET 4.0, but it is unclear at the moment how much of this will make it into the language (lambda compiler) in C# 4.0.
All you need (for delegate version) is:
public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{ // note: omitted arg/null checks
foreach(T item in source) { action(item); }
}
Then from any query you can simply use .ForEach(x => /* do something */)
.
For your specific example (populating a List<XElement>
), I'd do it this way.
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;
}
Also: Don't forget that List<T>
already implements .ForEach<T>()
, so to use it against any Enumerable<T>
, this is all the code you need.
myEnumerable.ToList().ForEach( x => myAction(x) );
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With