m.edmondson
m.edmondson

Reputation: 30922

Convert output of LINQ to Int16

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 'WhereSelectEnumerableIterator2[System.Collections.Generic.KeyValuePair2[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

Answers (4)

Kirk Broadhurst
Kirk Broadhurst

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

jason
jason

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

ebb
ebb

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

BrokenGlass
BrokenGlass

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

Related Questions