Reputation: 2695
In the simplified example below I want to define result
before it is assinged. The linq queries below return lists of anonymous types. result
will come out of the linq queries as an IEnumerable<'a> but I can't define it that way at the top of the method. Is what I am trying to do possible (in .NET 4)?
bool large = true;
var result = new IEnumerable(); //This is wrong
List<int> numbers = new int[]{1,2,3,4,5,6,7,8,9,10}.ToList<int>();
if (large)
{
result = from n in numbers
where n > 5
select new
{
value = n
};
}
else
{
result = from n in numbers
where n < 5
select new
{
value = n
};
}
foreach (var num in result)
{
Console.WriteLine(num.value);
}
EDIT: To be clear I know that I do not need anonymous types in the example above. It is just to illustrate my question with a small, simple example.
Upvotes: 3
Views: 802
Reputation: 3419
You could build the LINQ query in parts if you do not need any conditional parts after creating the anonymous type. Otherwise it is probably wiser to define a new struct/class to be used in place of anonymous type.
bool large = true;
List<int> numbers = new int[]{1,2,3,4,5,6,7,8,9,10}.ToList<int>();
IEnumerable<int> query;
if (large) {
query = query.Where(n => n > 5);
} else {
query = query.Where(n => n < 5);
}
var result = query.Select(n => new { Value = n });
foreach (var num in result) {
Console.WriteLine(num.Value);
}
Upvotes: 0
Reputation: 1502216
I like Snowbear's answer here if you actually have to do this... but personally I would at least try to avoid getting into this situation. For example, even keeping the anonymous types, I would change your original code to:
bool large = true;
var result = new IEnumerable(); //This is wrong
List<int> numbers = new int[]{1,2,3,4,5,6,7,8,9,10}.ToList<int>();
Func<int, bool> predicate = large ? new Func<int, bool>(x => x > 5)
: x => x < 5;
var result = numbers.Where(predicate)
.Select(x => new { value = x });
foreach (var num in result)
{
Console.WriteLine(num.value);
}
Note how this has removed duplication - it's clearer that the only thing that large
affects is the predicate.
I find that code ends up being clearer if variables are only assigned a single value, ideally at the point of declaration.
Obviously this isn't always feasible, but it's worth bearing in mind where possible. Where it's not possible, Snowbear's answer is fine and guaranteed to work.
Upvotes: 1
Reputation: 17274
Anonymous types can be declared only with var
. The good thing is that anonymous types with same properties will be the same types. If you really need it (in this sample you don't need it) then you can write:
var result = Enumerable.Repeat(new {value = 0}, 0); // stub value which will give needed type
if (...)
{
result = ...;
}
else
{
result = ...;
}
P.S.: this was possible even in previous .Net version (lower than 4.0)
Upvotes: 3
Reputation: 426
You have to define the type beforehand. E.g.
public class TheNumber
{
public int Number { get; set; }
}
....
IEnumerable<TheNumber> result;
result = numbers.Where(n => n > 5).Select(n => new TheNumber() { Number = n });
Upvotes: 0
Reputation: 24017
You can make it an IEnumerable and just select 'n' in your queries, rather than create an anonymous type. EG:
IEnumerable<int> result = null;
result = from n in numbers
where n > 5
select n;
If what you're actually doing requires an anonymous type, then--since you're using C# 4--you can declare IEnumerable<dynamic> result
, and the rest of your code will work.
Upvotes: 1