What''s the difference?
I'm using LINQ to develop a stock analyze tool, but meet a problem:
Error 2 Instance argument: cannot convert from 'System.Collections.Generic.IEnumerable<decimal?>' to 'System.Collections.Generic.IEnumerable<decimal>' C:\Documents and Settings\User\My Documents\Visual Studio 2008\Projects\StockAnalyze\StockAnalyze\Window1.xaml.cs 74 42 StockAnalyze
so, What's the difference between IEnumerable<decimal?> and IEnumerable<decimal>
and what's meaning of the IEnumerable<decimal?>.
thank you~
The question mark after a type means that the type is nullable (it can also hold null as a value), which is not possible in the standard data type. I think this was a C# 2.0 language feature.
This will help cope with situations when there is no data in the actual row column.
Hope this helps.
Ben
Hi,
Code Snippet
Decimal
? nullable = null; Decimal nonNull; if (nullable.HasValue) {
nonNull = nullable.Value;
//Exception - Nullable object must have a value. Console.WriteLine(nonNull); }
nonNull = nullable.GetValueOrDefault(0);
Console.WriteLine(nonNull); Two possible ways, one way is to check to see if the nullable type has a value and then use the value property. When using this approach, you need to check as if it doesn't have a value it will throw an exception.
My preferred way is to use GetValueOrDefault() passing in the default as a parameter. If the object is null, then the default value is returned. Makes the code cleaner.
Hope this answers your question.
Ben
List (which implements IEnumerable<>) has got a great method called ConvertAll. For each value, ConvertToNonNull is called to handle the process.
Code Snippet
static
void Main(string[] args) {
List<decimal> nonNull; List<decimal?> nullable = new List<decimal?>(); nullable.Add(
null); nullable.Add(1);
nonNull = nullable.ConvertAll(
new Converter<decimal?, decimal>(ConvertToNonNull)); foreach (var i in nonNull) {
Console.WriteLine(i); }
Console.ReadLine(); }
public static decimal ConvertToNonNull(decimal? nullValue) {
return nullValue.GetValueOrDefault(0); }
Sadly, the standard IEnumerable<> doesn't support anything like this. However, it got me thinking about how to do it.
My solution, was to use extension methods to add the ConvertAll functionality to IEnumerable.
Code Snippet
public
static class IEnumerableExtension {
public static IEnumerable ConvertAll(this IEnumerable collection, Converter converter) {
if (converter == null)
throw new ArgumentNullException("converter"); List list = new List();
foreach (T i in collection) {
list.Add(converter(i));
}
return list; }
}
I can then call it by using this code:
Code Snippet
IEnumerable
<decimal> notNull; IEnumerable<decimal?> INull; INull = nullable;
Console.WriteLine("Count: " + INull.Count()); notNull = INull.ConvertAll(
new Converter<decimal?, decimal>(ConvertToNonNull)); foreach (decimal i in notNull) {
Console.WriteLine(i); }
See my blog post on this @ http://blog.benhall.me.uk/2007/08/converting-ienumerable-to-ienumerable.html
Hope this solves your problem.
Ben