WITH#; The NullReferenceException was unhandled; reset to 0

When I try to call the ToString () method in the Deck class, it gives me the error "NullReferenceException was not processed". While doing some testing, I found out that when he tries to call the Deck.ToString () method, the size was set to 0. It should be set when the constructor is called, and I don’t know what reset it is.

The main method:

public class DeckTest { public static void Main() { Deck toTest = null; Console.WriteLine("What type of Deck would you like to create?"); toTest = new Deck(Console.ReadLine()); Console.WriteLine(toTest); } } 

Deck Class:

 class Deck { String type; int size; String deckList; Card[] deck; public Deck(String type, int size) { deck = new Card[size]; this.type = type; this.size = size; while (deck[size - 1] == null) { Card newCard; Console.WriteLine("Please Enter the Type, Name, Colour (if card has no Colour, enter 'Colourless'), Colour Identity, Text, Mana Cost (if applicable), Converted Mana Cost (if applicable), Power (if applicable), Toughness (if applicable), separated by semicolons."); String line = Console.ReadLine(); string[] card = line.Split(';'); if (card[0].Equals("Land", StringComparison.OrdinalIgnoreCase)) { newCard = new Card(card[0], card[1], card[3], card[4]); } else if (card[0].Equals("creature", StringComparison.OrdinalIgnoreCase)) { newCard = new Card(card[0], card[1], card[2], card[3], card[4], card[5], int.Parse(card[6]), int.Parse(card[7]), int.Parse(card[8])); } else { newCard = new Card(card[0], card[1], card[2], card[3], card[4], card[5], int.Parse(card[5])); } addCard(newCard); } } public Deck(String type) { if (type.Equals("Standard", StringComparison.OrdinalIgnoreCase)) { new Deck(type, 60); } else if (type.Equals("Extended", StringComparison.OrdinalIgnoreCase)) { new Deck(type, 60); } else if (type.Equals("Modern", StringComparison.OrdinalIgnoreCase)) { new Deck(type, 60); } else if (type.Equals("Commander", StringComparison.OrdinalIgnoreCase)|| type.Equals("EDH", StringComparison.OrdinalIgnoreCase)) { new Deck(type, 100); } } void addCard (Card newCard) { int count = 0; while (deck[count] != null && count < size) { count++; } if (count < size) { deck[count] = newCard; } else { Console.WriteLine("This deck is full."); } } public override string ToString() { String output = ""; int count = 0; while (deck[count] != null && count < size-1) { output += deck[count] + "/n"; } return output; } } 
+4
source share
3 answers

The new keyword creates an entirely new instance (which is quickly discarded) without modifying the existing instance from your constructor.

You should use the factory template (a static method that creates an instance of another object depending on its parameters, and then returns it):

 public static Deck FromType(String type) { if (type.Equals("Standard", StringComparison.OrdinalIgnoreCase)) { return new Deck(type, 60); } else if (type.Equals("Extended", StringComparison.OrdinalIgnoreCase)) { return new Deck(type, 60); } else if (type.Equals("Modern", StringComparison.OrdinalIgnoreCase)) { return new Deck(type, 60); } else if (type.Equals("Commander", StringComparison.OrdinalIgnoreCase)|| type.Equals("EDH", StringComparison.OrdinalIgnoreCase)) { return new Deck(type, 100); } throw new ArgumentOutOfRangeException("Bad type"); } 

Then you can create a new deck toTest = Deck.FromType(Console.ReadLine()) instead of the new keyword.

+3
source

I would say that this is not the best way to get an object, you can try something like:

 public class Deck { public static Deck GetDeck(String type) { if (type.Equals("Standard", StringComparison.OrdinalIgnoreCase)) { return new Deck(type, 60); } else if (type.Equals("Extended", StringComparison.OrdinalIgnoreCase)) { return new Deck(type, 100); } } } 

And how does Deck turn out:

 Deck.GetDeck("foo"); 
+2
source

To call another constructor, you do this in front of the body of the method, and not inside it:

 public Deck(String type) : this(type, type.Equals("Standard", StringComparison.OrdinalIgnoreCase) || type.Equals("Extended", StringComparison.OrdinalIgnoreCase) || type.Equals("Modern", StringComparison.OrdinalIgnoreCase) ? 60 : 100) { // nothing more here } 
+1
source

Source: https://habr.com/ru/post/1436734/


All Articles