Reputation: 30922
I've got the following LINQ expression:
var ageEntry = from entry in args
where (entry.Key == "Age")
select entry.Value;
//I want age as Int16:
Int16 age = Convert.ToInt16(ageEntry);
However I get the following exception:
Unable to cast object of type 'WhereSelectEnumerableIterator
2[System.Collections.Generic.KeyValuePair
2[System.String,System.String],System.String]' to type 'System.IConvertible'.
which isn't the clearest exception I've seen, can someone please explain this to me?
Upvotes: 1
Views: 1106
Reputation: 28728
LINQ Where
and Select
statements always return collections. Almost all LINQ operators return collections; sometimes the collection may have zero or one item, but it is a collection and you must operate on it as a collection.
The exceptions are
Single
SingleOrDefault
First
FirstOrDefault
Whenever you have a LINQ query and want to resolve it to a element rather than a collection you can use one of these operators, or an index operators like list[0]
Upvotes: 1
Reputation: 241711
First, ageEntry
is a sequence, being the result of a query. It looks like you expect your query to have a single result. Thus, you can say:
short age = Convert.ToInt16(ageEntry.Single());
which isn't the clearest exception I've seen, can someone please explain this to me?
Actually, it's pretty clear. It's telling you that the type of ageEntry
is WhereSelectEnumerableIterator2[System.Collections.Generic.KeyValuePair2[System.String,System.String],System.String]
and that it can't convert it. This is your major clue that ageEntry
isn't representing a number or something that can be converted to a number like you think it should be.
Rather, it represents a query that filters and projects a certain sequence (in your case, args
). Basically, ageEntry
knows how to filter through a sequence of KeyValuePair<string, string>
and project to string
. This is why you have to use Enumerable.Single
. You're saying "give me the one result from the query that results from doing all the filtering and projecting that you know how to do (by the way, throw an exception if there isn't a single result)."
Upvotes: 3
Reputation: 9377
ageEntry
is currently of type IEnumerable<string>
. You may want to do something like:
var ageEntry = args.Single(x => x.Key == "Age");
var age = Int16.Parse(ageEntry.Value);
Upvotes: 1
Reputation: 160952
Your input is currently an IEnumerable<string>
but you need a single string
value as input - try this:
Int16 age = Convert.ToInt16(ageEntry.Single());
This makes the assumption there is actually exactly one string value in your ageEntry
enumeration, otherwise it will throw an exception - Alternatives for Single()
depending on your actual scenario are First()
to take the first value regardless of how many are in the enumeration or FirstOrDefault()
to take the first or a default value if there is no value.
Upvotes: 0