Here's some code that (obviously) doesn't compile:
var q = from x in myAnonymousTypeCollection
select new {
x.ID,
CalcField = {
switch(x.SomeField) {
case 1:
return Math.Sqrt(x.Field1);
case 2:
return Math.Pow(x.Field2, 2);
default:
return x.Field3;
}
}
};
You get the picture; I'm trying to calculate CalcField
in a completely different way, depending on what the value of SomeField
is. I can't use a Func<>
(or can I?), because the input type is anonymous. So what's the right syntax to get this to work?
LINQ comes in two syntactical flavors: The Query and the Method syntax. They can do almost the same, but while the query syntax is almost a new language within C#, the method syntax looks just like regular C# method calls.
Query syntax and method syntax are semantically identical, but many people find query syntax simpler and easier to read. Some queries must be expressed as method calls. For example, you must use a method call to express a query that retrieves the number of elements that match a specified condition.
LINQ queries are always executed when the query variable is iterated over, not when the query variable is created. This is called deferred execution. You can also force a query to execute immediately, which is useful for caching query results. This is described later in this topic.
The Data Source This fact means it can be queried with LINQ. A query is executed in a foreach statement, and foreach requires IEnumerable or IEnumerable<T>. Types that support IEnumerable<T> or a derived interface such as the generic IQueryable<T> are called queryable types.
First off, I usually prefer the method chain syntax over the query syntax for Linq. With that you can do this easily.
var q = myAnonymousTypeCollection
.Select(x =>
{
object calcField;
switch(x.SomeField)
{
case 1:
calcField = Math.Sqrt(x.Field1);
case 2:
calcField = Math.Pow(x.Field2, 2);
default:
calcField = x.Field3;
return new
{
x.ID,
CalcField = calcField
};
});
Without using method chains, you need either a method or an Func. Let's assume a Func
//replace these with actual types if you can.
Func<dynamic, dynamic> calculateField =
x =>
{
switch(x.SomeField) {
case 1:
return Math.Sqrt(x.Field1);
case 2:
return Math.Pow(x.Field2, 2);
default:
return x.Field3;
}
var q = from x in myAnonymousTypeCollection
select new { x.Id, CalcField = calculateField(x) };
Note: I didn't write this in an IDE, so please excuse any simple errors.
Here is the MSDN for dynamic. However, I have found that once you need to start passing anonymous types around, it is best to make an actual class.
You could wrap your anonymous function as a (self-executing) Func<>
delegate. This assumes you know the return type.
var q = from x in myAnonymousTypeCollection
select new {
ID = x.ID,
CalcField = new Func<double>( () => {
switch(x.SomeField) {
case 1:
return Math.Sqrt(x.Field1);
case 2:
return Math.Pow(x.Field2, 2);
default:
return x.Field3;
}
} )()
};
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