I'm confused about why this object is null

  • Thread starter Thread starter SlurrerOfSpeech
  • Start date Start date
  • Tags Tags
    Confused
Click For Summary

Discussion Overview

The discussion revolves around a coding issue related to a NullReferenceException encountered while using a custom class in C#. Participants explore the reasons behind the exception, particularly focusing on the initialization of class properties.

Discussion Character

  • Technical explanation
  • Conceptual clarification
  • Debate/contested

Main Points Raised

  • One participant describes a class, FriendList, and its method that leads to a NullReferenceException, suggesting that the issue lies with the names property being uninitialized.
  • Another participant points out that either flist or flist.names could be null and recommends performing sanity checks before accessing properties.
  • Some participants discuss the misconception that class fields are automatically initialized, clarifying that unless explicitly done in a constructor, object fields remain null.
  • One participant acknowledges that they resolved their issue by creating a constructor for FriendList and initializing the names property as a new Dictionary.

Areas of Agreement / Disagreement

Participants generally agree on the necessity of initializing class properties in constructors, but there is some confusion about automatic initialization of fields in C#.

Contextual Notes

Limitations include the assumption that participants are familiar with C# and object-oriented programming concepts. The discussion does not resolve the broader implications of object initialization in different contexts.

SlurrerOfSpeech
Messages
141
Reaction score
11
I have a class like

Code:
    public class FriendList
    {
        public Dictionary<string, int> names { get; set; } // List of friends names and number of occurrences (in case two or more friends have the same name)
        public DateTime timestamp { get; set; } // date/time on the data file

        public static FriendList operator / ( FriendList first, FriendList second )
        {
            // Returns a FriendList of every friend in first but not second, with the timestamp
            // of the returned object being an arbitrary value. 
            FriendList firstNotSecond = new FriendList();
            foreach ( KeyValuePair<string,int> thisName in first.names  )
            {
                int secondNum = second.names.ContainsKey(thisName.Key) ? second.names[thisName.Key] : 0;
                if ( thisName.Value > secondNum )
                {
                    firstNotSecond.names[thisName.Key] = thisName.Value - secondNum;
                }
            }
            return firstNotSecond;          
        }

        public void PrintInfo ( )
        {
            Console.WriteLine("Friends from list timestamped with {0}", this.timestamp.ToString());
            foreach ( KeyValuePair<string, int> thisFriend in this.names )
            {
                Console.WriteLine("\t\t{0} ({1})", thisFriend.Key, thisFriend.Value);
            }
        }

        public int CountFriends ( )
        {
            int count = 0;
            foreach ( KeyValuePair<string, int> namein this.names )
            {
                count += name.Value;
            }
            return count;
        }

    }

but when I use that class in the following procedure

Code:
        private void BuildFriendHistory ( )
        {
            // Takes all text files currently in the Data folder
            // and extracts their friends lists into a List<FriendList>.
            // Prints any error encountered along the way.
            this._fhist = new List<FriendList>();
            foreach ( string thisFilePath in Directory.GetFiles(this._datadir) )
            {
                FriendList flist = new FriendList();
                string line;
                System.IO.StreamReader file = new System.IO.StreamReader(thisFilePath);
                while ( (line = file.ReadLine()) != null )
                {
                    int k = line.LastIndexOf(' ');
                    flist.names[line.Substring(0, k)] = Int32.Parse(line.Substring(k + 1));
                }
                this._fhist.Add(flist);
            }
        }

I'm getting a NullReferenceException on the line

Code:
flist.names[line.Substring(0, k)] = Int32.Parse(line.Substring(k + 1))

and I know (because I've stepped through and checked) that

Code:
line.Substring(0, k)

and

Code:
Int32.Parse(line.Substring(k + 1))

are not NULL. Therefore NULL is some part of

Code:
flist.names

and I'm wondering if you can help me figure out why.
 
Technology news on Phys.org
Mods, you can remove this thread. I figured out my problem (Needed to create a constructor for FriendList objects and in that constructor intialize this.names = new Doctionary<string,int> () )
 
C:
while ( (line = file.ReadLine()) != null )
{
      int k = line.LastIndexOf(' ');
      flist.names[line.Substring(0, k)] = Int32.Parse(line.Substring(k + 1));
}
this._fhist.Add(flist);
Either flist is null or flist.names is null. Before drilling down to flist.names[line.Substring(0, k)], you should do some sanity check to make sure that neither of this is null. Nowhere in the code you posted did I see anything where flist is initialized, which you're probably already figured out.

BTW, just because a problem gets solved, we don't automatically delete a thread.
 
Mark44 said:
Either flist is null or flist.names is null. Before drilling down to flist.names[line.Substring(0, k)], you should do some sanity check to make sure that neither of this is null. Nowhere in the code you posted did I see anything where flist is initialized, which you're probably already figured out.

I thought that if you have a class like

Code:
public class MyClass
{
    SomeType MyField1 { get; set; }
    SomeOtherType MyField2 { get; set; }
}

then both fields are implicitely newed when creating a new MyClass.
 
SlurrerOfSpeech said:
I thought that if you have a class like

Code:
public class MyClass
{
    SomeType MyField1 { get; set; }
    SomeOtherType MyField2 { get; set; }
}

then both fields are implicitely newed when creating a new MyClass.
Your code is C#, right? Assuming you have a constructor for MyClass, space is allocated for the data members of MyClass, but unless the constructor initializes these members explicitly they wil be initialized to 0 in some form, for numbers, and null if they are objects of some kind.
 
Mark44 said:
Your code is C#, right? Assuming you have a constructor for MyClass, space is allocated for the data members of MyClass, but unless the constructor initializes these members explicitly they wil be initialized to 0 in some form, for numbers, and null if they are objects of some kind.

Got it. Thanks!
 

Similar threads

  • · Replies 2 ·
Replies
2
Views
1K
  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 4 ·
Replies
4
Views
1K
  • · Replies 9 ·
Replies
9
Views
2K
  • · Replies 9 ·
Replies
9
Views
3K
Replies
3
Views
1K
  • · Replies 9 ·
Replies
9
Views
3K
  • · Replies 3 ·
Replies
3
Views
3K
  • · Replies 3 ·
Replies
3
Views
4K
Replies
2
Views
3K