336 votes

Quand dois-je utiliser un struct au lieu d’une classe ?

MSDN dit que vous devez utiliser des structs lorsque vous avez besoin des objets légers. Existe-t-il un tout autre scénario lorsqu’un struct est préférable sur une classe ?

Edit :
Certaines personnes oublient que :

  1. structs peuvent avoir des méthodes !
  2. structs n’ont aucun héritage capabilites.

Un autre Edit :
Je comprends les différences techniques, je n’ai pas une bonne idée pour quand utiliser un struct.

319voto

OwenP Points 11164

MSDN a la réponse: Le choix Entre les Classes et les Structures.

Fondamentalement, cette page vous donne un 4-élément de la liste de contrôle et préconise l'utilisation d'une classe, à moins que votre type répond à tous les critères.

Ne pas définir une structure, à moins que le type a toutes les conditions suivantes caractéristiques:

  • Logiquement, il représente une valeur unique, semblables à des types primitifs (integer, double, et ainsi de suite).
  • Il a une instance de taille de moins de 16 octets.
  • Il est immuable.
  • Elle n'aura pas à être mis en boîte fréquemment.

58voto

Andrei Rînea Points 7554

Je suis surpris de n'avoir lu aucune des réponses précédentes, que je considère comme l'aspect le plus crucial:

J'utilise des structs quand je veux un type sans identité. Par exemple un point 3D:

 public struct ThreeDimensionalPoint
{
    public readonly int X, Y, Z;
    public ThreeDimensionalPoint(int x, int y, int z)
    {
        this.X = x;
        this.Y = y;
        this.Z = z;
    }

    public override string ToString()
    {
        return "(X=" + this.X + ", Y=" + this.Y + ", Z=" + this.Z + ")";
    }

    public override int GetHashCode()
    {
        return (this.X + 2) ^ (this.Y + 2) ^ (this.Z + 2);
    }

    public override bool Equals(object obj)
    {
        if (!(obj is ThreeDimensionalPoint))
            throw new ArgumentException();
        ThreeDimensionalPoint other = (ThreeDimensionalPoint)obj;
        return this == other;
    }

    public static bool operator ==(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2)
    {
        return p1.X == p2.X && p1.Y == p2.Y && p1.Z == p2.Z;
    }

    public static bool operator !=(ThreeDimensionalPoint p1, ThreeDimensionalPoint p2)
    {
        return !(p1 == p2);
    }
}
 

Si vous avez deux instances de cette structure, vous vous en fichez s'il s'agit d'une seule donnée en mémoire ou deux. Vous vous souciez seulement de la valeur (s) qu'ils détiennent.

32voto

Bart Gijssens Points 586

Le projet de loi Wagner a un chapitre à ce sujet dans son livre "effective c#" (http://www.amazon.com/Effective-Specific-Ways-Improve-Your/dp/0321245660). Il conclut en utilisant le principe suivant:

  1. Est la principale responsabilité du type de stockage de données?
  2. Est son public interface définie entièrement par des propriétés que l'accès ou de modifier ses données membres?
  3. Êtes-vous sûr de votre type n'aura jamais les sous-classes?
  4. Êtes-vous sûr de votre type ne sera jamais traitée polymorphically?

Si vous répondez " oui " à tous les 4 questions: utilisation d'une struct. Sinon, utilisez un classe.

17voto

Simon Steele Points 8344

Utilisez une structure lorsque vous voulez une sémantique de type valeur au lieu de type référence. Les structs sont copiés en fonction de la valeur alors soyez prudent!

Voir aussi les questions précédentes, par exemple

http://stackoverflow.com/questions/13049/whats-the-difference-between-struct-and-class-in-net

14voto

Pawel Pabich Points 818

Je voudrais utiliser les structures lorsque:

  1. un objet est censé être en lecture seule(chaque fois que vous passez/attribuer un struct il est copié). Lire uniquement les objets sont grands quand il s'agit de traitement multithread, car ils ne font pas de se venger de verrouillage dans la plupart des cas.

  2. un objet est petit et court-séjour. Dans un tel cas, il ya une bonne chance que l'objet sera alloué sur la pile, ce qui est beaucoup plus efficace que de le mettre sur le tas managé. Qu'est-ce que plus de la mémoire allouée par l'objet sera libéré dès qu'il se passe en dehors de son champ d'application. En d'autres mots, c'est moins de travail pour le Garbage Collector et la mémoire est utilisée plus efficace.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X