Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FirstOrDefault() method of System.linq.Enumerable namespace throwing NullReferenceException [duplicate]

Tags:

c#

.net

linq

I have a static readonly collection of user defined object type which is initialized like below.

private static readonly List<MyClass> obj = new List<MyClass>();

Another public utility method fills this collection and return the collection back.

public static List<MyClass> GetMyClasses(){

// some code for DB calls goes here
// in a loop based on recordset, i fill the collection like below
obj.Add(new MyClass(){// my class property settings based on DB values});

// finally return the collection
return obj;
}

I am getting the 'object refrence not set to an instance of an object' on 'ac' object in below line.

var cl = TestClass.GetMyClasses().FirstOrDefault(ac => ac.name == "myname")

I would like to know why 'ac' object is NULL here, even if we the collection is empty, as per MSDN FirstOrDefault should return NULL for reference types if it does't find the match.

Can somebody help me understand what i am missing here? The same code was working flawlessly for months before it started throwing exception today. The same code is working well even today on other server without issues.

For security reasons i can't post the entire exception stack trace but, it is pointing to below IL code

at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source, Func`2 predicate)

Updating the question with sample similar code of the issue.

public static class DemoDataAccess
    {
        private static readonly List<MyTestClass> classes
            = new List<MyTestClass>();

        public static IList<MyTestClass> GetMyClasses()
        {
            using (var cnn = new SqlConnection(@"connection string goes here"))
            {
                cnn.Open();
                using (var cmd = new SqlCommand("SP Name", cnn))
                {
                    cmd.CommandType = CommandType.StoredProcedure;
                    using (SqlDataReader rdr = cmd.ExecuteReader())
                    {
                        while (rdr.Read())
                        {
                            classes.Add(new MyTestClass()
                                       {
                                         Id = Convert.ToInt32(rdr["id"]),
                                         Name = Convert.ToString(rdr["name"])
                                       });
                        }
                    }
                }
            }

            return classes;
        }
    }


public class MyTestClass
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Consistenly exception is thrown on below line and stack trace is point to 'ac' instance.

var obj = DemoDataAccess
             .GetMyClasses()
             .FirstOrDefault(ac => ac.Name == "something");
like image 445
Azeez Avatar asked Sep 21 '13 18:09

Azeez


People also ask

What is FirstOrDefault in linq?

In LINQ, FirstOrDefault() Operator is used to return the first element from the list/collection. FirstOrDefault() Operator is same as LINQ First() Operator and the only difference is, in case if the lists returns no elements then LINQ FirstOrDefault operator method will return default value.

What does FirstOrDefault do?

FirstOrDefault<TSource>(IEnumerable<TSource>)Returns the first element of a sequence, or a default value if the sequence contains no elements.

How to set default value in FirstOrDefault in c#?

The default value for reference and nullable types is null . The FirstOrDefault method does not provide a way to specify a default value. If you want to specify a default value other than default(TSource) , use the DefaultIfEmpty<TSource>(IEnumerable<TSource>, TSource) method as described in the Example section.

Can first or default return Null?

The major difference between First and FirstOrDefault is that First() will throw an exception if there is no result data for the supplied criteria whereas FirstOrDefault() returns a default value (null) if there is no result data.


1 Answers

I would like to know why 'ac' object is NULL here, even if we the collection is empty, as per MSDN FirstOrDefault should return NULL for reference types if it does't find the match.

This shows that GetMyClasses() returns a collection which have a null element before any element matching your predicate. That's not the same as the collection being empty.

Check it with this:

int nullElements = TestClass.GetMyClasses().Count(ac => ac == null);

I strongly suspect that you'll find nullElements is non-zero.

If that's not the problem, then you should work on providing a short but complete program which you can post. You don't need to post the real code - just code which shows the same problem. I'd be very surprised to see such code - it seems much more likely to me that you've somehow got a null element at the start, which would certainly explain the exception you're seeing.

As an aside, ac isn't an object - it's a variable (a lambda expression parameter). It's very important to distinguish between objects, variables, and references. An object can never be null - the value of a variable can be.

like image 65
Jon Skeet Avatar answered Sep 23 '22 02:09

Jon Skeet