2010-04-14 1 views
1

J'essaie de comprendre ce que l'approche correcte pour un constructeur qui accepte un tableau d'octets en ce qui concerne la façon dont il stocke les données de elle (en particulier avec PhysicalAddress)Quelle est l'approche appropriée pour la construction d'un objet PhysicalAddress de Tableau d'octets

J'ai un tableau de 6 octets (l'adresse) qui est construit une fois.

J'ai un tableau source de 18 octets (theAddresses) qui est chargé à partir d'une connexion TCP. Puis, je copie les 6 octets de l'adresseAddress + offset dans l'Address et je construis l'adresse physique à partir de celle-ci.

Le problème est que le PhysicalAddress juste stocke la référence au tableau qui a été passé. Par conséquent, si vous vérifiez ensuite les adresses qu'ils ne pointez jamais à la dernière adresse qui a été copié dans.

Quand je pris un coup d'oeil à l'intérieur de l'adresse physique avec réflecteur, il est facile de voir ce qui se passe.

public PhysicalAddress(byte[] address) 
{ 
    this.changed = true; 
    this.address = address; 
} 

Maintenant, je sais que cela peut être résolu en créant ensemble theAddress sur chaque passe, mais je voulais savoir ce qui est vraiment la meilleure pratique pour cela.

  1. Si le constructeur d'un objet qui accepte un tableau d'octets créer sa propre variable privée pour tenir les données et la copie de l'original
  2. Faut-il tenir juste la référence à ce qui a été transmis.
  3. Dois-je simplement créer l'adresse sur chaque passe dans la boucle

Répondre

1

Je dirais en général que la meilleure pratique sans autres considérations de conception spécifiques à considérer est certainement (1) le constructeur d'un objet qui accepte un tableau d'octets devrait créer sa propre variable privée pour Holdin g les données et copiez-les à partir de l'original.

1

Il me semble que votre constructeur devrait ressembler à ceci:

public PhysicalAddress(byte[] source, int offset) 
{ 
    // Validate arguments here :) 
    this.changed = true; 
    this.address = new byte[6]; 
    Buffer.BlockCopy(source, offset, address, 0, 6); 
} 

De cette façon, vous pouvez simplement faire la copie une fois à partir du tableau 18 octets d'origine. Prendre une copie défensive ressemble à la bonne approche ici - mais vous n'avez besoin de le faire qu'une seule fois. Il est logique de faire cela dans le constructeur lui-même plutôt que de forcer PhysicalAddress à croire que quel que soit le code appelant, il ne changera pas le tableau par la suite.

+0

Ce n'est pas mon constructeur, il fait partie du .NETFramework 2.0 et 3.5 est le même. (system.net.networkinformation) –

+1

@Paul: Wow, ça craint. Eh bien, je suppose que j'ai répondu à votre question sur les «meilleures pratiques» - mais quand on vous présente une telle classe, vous devrez faire une copie défensive, essentiellement :( –

Questions connexes