views:

234

answers:

5

Can anyone explain how on earth the following statement can generate

System.InvalidOperationException: The value null not be assigned a member of type System.Boolean since it is a value type that cannot have the value null (freely translated from Swedish (see also)).

if (user.Friends.Count() == 0)

user is a User and Friends is an IEnumerable<User>.

Update: Friends is returned from a linq to sql call and is actually a WhereSelectEnumerableIterator. It is empty in this case so I had expected the above to evaluate to true. In cases when Friends is not empty this works fine. So for some reason when it's empty havoc descends, it'd be nice to know why, but I guess what I'm really asking is, what's the workaround?

+3  A: 

Split up the code line, and see what error is reported:

int temp = user.Friends.Count();
if (temp == 0)

Then split up the first line if the problem is still unclear.

Douglas Leeder
See comment above.
Martin
A: 

If it's a list, then Count() appears to be wrong, that would be a property i.e. Count? Can you confirm this?

Hope this helps, Best regards, Tom.

tommieb75
First, he said "`Friends` is an `IEnumerble`." Second, either way, `List<T>` is an `IEnumerable<T>` and therefore there is an extension method `Enumerable.Count<T>.` Lastly, he is having a runtime issue, not a compile-time issue.
Jason
@Jason: Oh...bummer....thanks for pointing out this where I misunderstood!
tommieb75
+7  A: 

user.Friends is a lazy-evaluated enumeration (yield return or an Linq query), and something inside the evaluation is throwing the exception. Without more code it's impossible to say exactly where.

280Z28
This is as far as it goes: public IEnumerable<User> Friends { get { var friends = from u2g in FriendUserGroup.User2GroupLinks select u2g.User; return friends; } }
Martin
A: 

The Friends IEnumerable appears to have not been initialized. For example, the snippet below does not give a runtime error, because in Main(), I set Friends to a generic list.

public sealed class Program
    {
        public static void Main()
        {
            var user = new User
                           {
                               Friends = new List<Int32>()
                           };

            if (user.Friends.Count() == 0)
            {
                // TODO: Input logic here
            }
        }
    }

    /// <summary>
    /// User class
    /// </summary>
    public class User
    {
        /// <summary>
        /// Gets or sets the friends.
        /// </summary>
        /// <value>The friends.</value>
        public IEnumerable<Int32> Friends
        {
            get; set;
        }
    }
Bobby
We've established that it's a WhereSelectEnumerableIterator and that probably there's a failing somewhere within WhereSelectEnumerableIterator.Count().
Martin
+1  A: 

As I wrote in a comment to 280Z28, the getter looks like this.

    public IEnumerable<User> Friends
    {
        get
        {
            var friends = from u2g in FriendUserGroup.User2GroupLinks
                           select u2g.User;
            return friends;
        }
    }

FriendUserGroup.User2GroupLinks is an EntitySet. Its Count property is what throws the exception. Any() will also, in case anybody was wondering. What you need to do instead is to check HasLoadedOrAssignedValues. So I inserted

if (!FriendUserGroup.User2GroupLinks.HasLoadedOrAssignedValues)
    return null;

in the getter above.

I hate answering my own question when other people have put in effort. Thanks for all the input!

Martin