nGX
nGX

Reputation: 1068

Exception when adding item to list<t>

I always get a "An unhandled exception of type 'System.NullReferenceException' occurred in myapp.exe" when code reaches _match.Players2.Add(_hero);

I am not sure why, I initialized _match as well as _hero, when I debug I see that there are no null values. I am not sure why I am getting this exception, am I missing something?

Here is my code:

public static List<MyDotaClass.MatchHistory> GetMatchHistory(string uri)
{
    var HeroCollection = new List<MyDotaClass.DotaHero>();
    var MatchCollection = new List<MyDotaClass.MatchHistory>();

    string response = GetDotaWebResponse(uri);
    dotadata.Dota.MatchHistoryRootObject matches = JsonConvert.DeserializeObject<dotadata.Dota.MatchHistoryRootObject>(response);
    foreach (var match in matches.result.matches)
    {
        var _match = new MyDotaClass.MatchHistory();
        _match.MatchID = match.match_id.ToString();

        foreach (var player in match.players)
        {
            var _hero = new MyDotaClass.DotaHero();

            foreach(var h in heros)
            {
                if(player.hero_id.ToString().Equals(h.HeroID))
                {
                    _hero.HeroName = h.HeroName;
                    _hero.HeroNonCleanName = h.HeroNonCleanName;
                    _hero.HeroID = h.HeroID;
                    _match.Players2.Add(_hero);
                }
            }
        }
        MatchCollection.Add(_match);
    }
    return MatchCollection;
}

public class MyDotaClass
{
    public class DotaHero
    {
        public string HeroName { get; set; }
        public string HeroNonCleanName { get; set; }
        public string HeroID { get; set; }
    }

public class MatchHistory
{
    public string MatchID { get; set; }
    //public List<DotaHero> Players { get; set; }
    public List<MyDotaClass.DotaHero> Players2 { get; set; }
}

UPDATE:

For those interested in Dota, I lost all of my original code so I am rewriting and doing my best to make a tutorial out of it. http://uglyvpn.com/2014/07/21/dota-2-net-c-tool-pt1/

Upvotes: 0

Views: 80

Answers (3)

evanmcdonnal
evanmcdonnal

Reputation: 48076

You initialized the MatchHistory instance but not the Players2 property so it's still null.

You probably want to allocate it in the constructor like this although there are other options;

public MatchHistory()
{
    Players2 = new List<MyDotaClass.DotaHero>();
}

PS LoL > Dota :p

Upvotes: 1

Yair Nevet
Yair Nevet

Reputation: 13003

It is look like your Players2 collection is not instantiated, so do it first:

this.Players2 = new List<MyDotaClass.DotaHero>();

and then you would be able to refer and use it:

_match.Players2.Add(_hero);

As for where to instantiate it, do it in the constructor of MatchHistory:

public MatchHistory() {
    this.Players2 = new List<MyDotaClass.DotaHero>();
}

This is a good practice, because next time, even if you will forget to instantiate it, the constructor will do it automatically for you.

Otherwise, you'd keep getting: System.NullReferenceException

UPDATE:

You can't use this in a static context, change this method in order to enjoy from the constructor-base instantiating:

public static List<MyDotaClass.MatchHistory> GetMatchHistory(string uri)

to this:

public List<MyDotaClass.MatchHistory> GetMatchHistory(string uri)

Upvotes: 1

p.s.w.g
p.s.w.g

Reputation: 148990

Make sure the list in Players2 is initialized properly. It could be done in your foreach loop, like this:

foreach (var match in matches.result.matches)
{
    var _match = new MyDotaClass.MatchHistory();
    _match.MatchID = match.match_id.ToString();
    _match.Players2 = new List<MyDotaClass.DotaHero>();
    ...

But that's not a great design. It would be more robust to initialize it in the MatchHistory constructor, like this:

public class MatchHistory
{
    public string MatchID { get; set; }

    //public List<DotaHero> Players { get; set; }

    public List<MyDotaClass.DotaHero> Players2 { get; private set; }

    public MatchHistory() {
        this.Players2 = new List<MyDotaClass.DotaHero>();
    }
}

Note that I have also made the setter private here, as there should be no need to modify the value of this property after it's been initialized in the constructor.

Upvotes: 2

Related Questions