7

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");
BartoszKP
  • 34,786
  • 15
  • 102
  • 130
Azeez
  • 71
  • 1
  • 3

2 Answers2

6

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.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thank you Jon. I verified that the collection did not have any null element(s) in it. It could be all objects of type MyClass or none. Thats true, 'ac' is not an object here, i meant an instance of type MyClass in the collection. – Azeez Sep 21 '13 at 19:07
  • @user2802585: It's not that, either. It's a variable, that's all. Its value can be `null`, or a reference to an instance of `MyClass`. But I really think you need to work on reproducing this in code that we can all see. I think it *highly* unlikely that you've found a bug in `FirstOrDefault`. – Jon Skeet Sep 21 '13 at 19:17
  • @MetroSmurf: I have no idea how we're meant to interpret your comment. – Jon Skeet Sep 21 '13 at 20:01
  • You: _This shows that `GetMyClasses()` returns a collection which starts with a null element._ Or it returns a collection where a `null` member occurs before any member whose `.name` is `"myname"` exactly. – Jeppe Stig Nielsen Sep 21 '13 at 20:19
  • @JonSkeet - it was a failed humorous attempt of an object never being null. – Metro Smurf Sep 21 '13 at 23:27
  • Thanks for replys folks. I will put more logging and null reference check to find what is going wrong with this collection. Surprisingly, other server which got the same code and same data source do not have this issue. – Azeez Sep 22 '13 at 03:27
0

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?

MichaC
  • 13,104
  • 2
  • 44
  • 56
  • Yes, other method can also read from that collection and that method can run under a different thread. – Azeez Sep 21 '13 at 19:37