J'ai une boucle foreach qui traverse un tableau d'une classe et a une instruction if qui utilise l'une des propriétés de la classe, mais cela ne fonctionne pas. J'obtiens cette erreur:
Board.Boat.length n'est pas accessible avec une référence d'instance; qualifiez-le plutôt avec un nom de type.
Comment résolvez-vous cela, voici le code. Gardez à l'esprit que ce n'est toujours pas terminé.
using System;
using System.Collections.Generic;
using System.Numerics;
namespace BattleShip
{
class Board
{
class Boat
{
// This class is made for storing the meta-data of each individual boat
// Determines the start point
static int[,] pos = new int[xBoardSize, yBoardSize];
// Determines the direction of the boat (0 = horizontal, 1 = vertical)
static int direction = 0;
// Keeps track of the boat's size
static int length = 1;
// Keeps track if tile is hit or untouched
static int[] stateList;
// Searches fora oat object and
static Boat SearchForBoat (Vector2 coords, Boat[] database)
{
foreach (Boat boat in database)
{
for (int i = 0; i < boat.length; i++)
}
}
}
// These variables determine the size of the board
static int xBoardSize = 10;
static int yBoardSize = 10;
}
}
4 Réponses :
C'est parce que la propriété length est statique . De telles propriétés sont plutôt des propriétés de classe, tandis que d'autres sont des propriétés d'instance, c'est-à-dire que le champ static est utilisé avec le type (et l'autre avec l'objet instancié d'une classe). Dans votre cas, il devrait s'agir de Boat.length au lieu de boat.length .
Remarque: vous devriez considérer ces propriétés statiques, car length me semble qu'elle devrait dépendre d'un objet particulier, donc ne devrait pas être statique .
Une erreur vous indique que vous essayez d'accéder à une propriété statique à partir d'une instance d'objet.
public class Board
{
// These variables determine the size of the board
public const int XBoardSize = 10;
public const int YBoardSize = 10;
// a board has an array of boats, seems logical
public Boat[] Boats { get; set; }
// a board can find boats on it
public Boat SearchForBoat(Vector2 coords )
{
foreach (var boat in Boats)
{
for (int i = 0; i < boat.Length; i++)
/// do stuff here
}
}
}
// concrete boat class, which you can make instances from
public class Boat
{
// notice not static, we are saying an individual "boat" can have these properties
public int[,] Pos = new int[Board.XBoardSize, Board.YBoardSize];
public int Direction { get; set; }
public int Length { get; set; } = 1;
public int[] StateList { get; set; }
}
Cependant, comme la longueur est statique, techniquement, l'instance de bateau n'a pas de propriété appelée length .
J'ai pris la liberté de SRP ( principe de responsabilité unique) et normaliser votre code
Le principe de responsabilité unique est une programmation informatique principe qui stipule que chaque module, classe ou fonction 1 doit avoir la responsabilité d'une seule partie de la fonctionnalité fournie par le logiciel, et cette responsabilité devrait être entièrement encapsulé par la classe, le module ou la fonction.
En tant que tel, il a supprimé tous vos static guff
Utilisez le modificateur static pour déclarer un membre statique, qui appartient à le type lui-même plutôt que vers un objet spécifique.
foreach (Boat boat in database) // give me each real boat from database
{
for (int i = 0; i < boat.length; i++) // access an individual boat length
J'ai plusieurs commentaires pour votre code:
Le premier élément statique doit être considéré comme quelque chose d'unique. C'est quelque chose comme une valeur globale partagée par toutes les instances d'objet
De Documentation Microsoft sur statique
Le membre static peut être appelé sur une classe même si aucune instance de la classe n'a été créée. Le membre statique est toujours accessible par le nom de la classe, pas par le nom de l'instance. Une seule copie d'un membre statique existe , quel que soit le nombre d'instances de la classe créées.
Dans cet esprit, votre classe Bateau deviendra:
public class Board
{
private Boat[] boats;
public Board(Boat[] boats) {
// initialize th boats for the specific game
this.boats = boats
}
Boat SearchForBoat (Vector2 coords)
{
foreach (Boat boat in boats)
{
for (int i = 0; i < boat.length; i++)
}
}
// These variables determine the size of the board
int xBoardSize = 10;
int yBoardSize = 10;
}
Vos bateaux devraient maintenant faire partie de votre Conseil avec une relation Has-A :
public class Boat
{
// This class is made for storing the meta-data of each individual boat
// Determines the start point
public int[,] pos = new int[xBoardSize, yBoardSize];
// Determines the direction of the boat (0 = horizontal, 1 = vertical)
public int direction = 0;
// Keeps track of the boat's size
public int length = 1;
// Keeps track if tile is hit or untouched
public int[] stateList;
}
Ensuite, vous devez initialiser via un constructeur et utiliser les instances spécifiques
Le membre statique peut être appelé sur une classe même si aucune instance de la classe n'a été créée. Le membre statique est toujours accessible par le nom de la classe, pas par le nom de l'instance.
for (int i = 0; i < boat.length; i++) //wrong access static from an instance for (int i = 0; i < Boat.length; i++) //correct access static from the type itself (class itlsef)lire ici pour plus d'informations
Si vous convertissez tous vos membres et méthodes
staticen instance , vous résoudrez votre problème, utilisez uniquementstaticquand vous en avez absolument besoin.Boatdoit être autonome ... Pensez-y. Si vous fabriquez 2 bateaux, doivent-ils partager la même longueur? si vous déplacez une position de bateaux, cela devrait-il déplacer toutes les autres positions de bateaux?