简体   繁体   中英

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

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");

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.

First the obvious stuff: You are accessing

...ac.name == "..."

At this point, if ac is null, you'll get a null pointer exception. This also means, for some reason your collection contains NULL elements.

Now, according to the code you copied, it is impossible that there are NULL elements, either this is not the full code, and there is a glitch which inserts NULL into the list, or there must be some other place in your application which actually changes the collection and sets elements to null.

:edit: Do you have any async or parallel code execution between populating and reading the array?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM