2010-08-14 7 views
1

La meilleure façon d'expliquer mon problème est avec un extrait de code:type C# valeur avec un nombre dynamique de champs

enum Resource { ..., Size } 
class ResourceVector 
{ 
    int[] values = new int[(int)Resource.Size]; 

    public static ResourceVector operator + (ResourceVector a, ResourceVector b) 
    {...} 

    ... 
} 

Nous utilisons partout ce type comme si elle était un type de valeur. C'est à dire. nous faisons l'hypothèse que:

ResourceVector b = a; 
b += c; 

n'affectera pas a, parce que c'est la façon dont nous sommes habitués à parler de vecteurs (et c'est ainsi un vecteur avec un nombre fixe de champs ne se comporte, si elles sont appliquées comme struct). Cependant, comme cette hypothèse est fausse, elle a conduit à des bogues extrêmement subtils.

Je me demande s'il y a un moyen de faire ce comporter comme un type de valeur, autre que simplement l'élargissement des membres de Resource chacun dans leurs propres membres dans une struct ResourceVector (qui exige de toucher tous les membres de ResourceVector si nous voulons ajouter un autre Resource).

Oh, juste au cas où, nous travaillons avec C# 2.0. Donc pas de fonctionnalités fantaisies :-)

Merci.

+1

Rendre immuable? http://weblogs.asp.net/bleroy/archive/2008/01/16/immutability-in-c.aspx –

+0

On dirait que vous essayez de faire un drapeau enum? Si c'est le cas, faites-le au lieu de cela :) SI ce n'est pas le cas, marquez simplement struct, transmettez les valeurs dans un ctor, exposez-les comme une collection en lecture seule (ou renvoyez une copie du tableau), et off-hand disons que vous êtes bien (assurez-vous qu'il est immuable une fois que le ctor est fait :) –

+0

donc si la structure dont vous avez besoin, pourquoi ne pas le transformer en struct et avoir vos méthodes opérateur retourner une nouvelle instance au lieu de modifier celui existant? –

Répondre

4

Je pense que vous confondez "type de valeur" avec "type immuable". Vous voulez réellement que votre ResourceVector soit un de type immutable.

Un type immuable est celui qui n'a aucun moyen de changer son contenu. Une fois construite, une instance conserve sa valeur jusqu'à ce qu'elle soit récupérée. Toutes les opérations telles que l'addition renvoient une nouvelle instance contenant le résultat au lieu de modifier une instance existante.

string est la classe immuable la plus connue. Toutes les opérations comme Substring et Replace renvoient une nouvelle chaîne et ne modifient pas les chaînes existantes.

Une fois que votre type est correctement immuable, sémantiquement, peu importe qu'il s'agisse d'un type de valeur ou d'un type de référence, mais cela a de l'importance pour la performance. Si vous passez beaucoup de valeurs, vous devriez probablement en faire un type de référence afin d'éviter de nombreuses copies inutiles.

+0

Pour une raison quelconque, j'ai pensé que cela ne fonctionnerait pas avec '+ ='. Mais il s'avère que c'est bon. (Ceci est très embarrassant, car je suis un programmeur Haskell. * Que voulez-vous dire immutable? * :-P) – luqui

Questions connexes