locked
What's the difference? RRS feed

  • Question

  •  

    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~

    Wednesday, August 15, 2007 7:44 AM

Answers

  • 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

    Wednesday, August 15, 2007 8:41 AM
  • 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

    Wednesday, August 15, 2007 9:08 AM
  • 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

    Wednesday, August 15, 2007 10:22 AM
  • Or you can use lambda expression and Linq extensions like this:

     

    Code Snippet

    IEnumerable<decimal?> nullable = new List<decimal?> { null, 1 };

    IEnumerable<decimal> nonNull = nullable.Select(s => s.GetValueOrDefault(0));

    Console.WriteLine(string.Join(", ", nonNull.Select(s => s.ToString()).ToArray()));

     

     

    Vlad

    Saturday, August 18, 2007 10:00 AM

All replies

  • 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

    Wednesday, August 15, 2007 8:41 AM
  •  

    Thank you ~

     

    And how to convert it into the type without the question mark?

    Wednesday, August 15, 2007 9:02 AM
  • 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

    Wednesday, August 15, 2007 9:08 AM
  • This is one method to covert ONE variable to non-nullable variables.

     

    Is there any short cut to convert a IEnumerable<> of nullable types into its non-nullable types?

     

    thank you~

    Wednesday, August 15, 2007 9:15 AM
  • 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

    Wednesday, August 15, 2007 10:22 AM
  • Your reply is very helpful.

     

    Thank you ~~

    Wednesday, August 15, 2007 11:11 AM
  • Or you can use lambda expression and Linq extensions like this:

     

    Code Snippet

    IEnumerable<decimal?> nullable = new List<decimal?> { null, 1 };

    IEnumerable<decimal> nonNull = nullable.Select(s => s.GetValueOrDefault(0));

    Console.WriteLine(string.Join(", ", nonNull.Select(s => s.ToString()).ToArray()));

     

     

    Vlad

    Saturday, August 18, 2007 10:00 AM
  • Your solution is really cool~

    Saturday, August 18, 2007 7:24 PM