2009-08-11 6 views
3

Dans VB.NET, pourquoi ne puis-je pas voir un membre d'une structure lorsque je lui attribue un type Nullable?Impossible de voir les membres d'une structure déclarés comme valables

Exemple:

Public Structure myNullable 
    Dim myNullVar As Integer 
End Structure 

Sub Main() 
    Dim myInstance As myNullable 'This works. 
    Dim myNullableInstance? As myNullable 'This works. 
    myInstance.myNullVar = 1 'This works.  
    myNullableInstance.myNullVar = 1 'This doesn't work. 
End Sub 
+0

Que faites-vous qui a besoin d'une structure? Je ne vois pas beaucoup d'utilisation pour les structures pour la plupart des programmes .net, en particulier les gens qui apprennent .net – Maslow

+0

Qu'est-ce que tu fais qui ne fonctionnerait pas avec Dim myNullVar As 'Integer?' enveloppé dans une classe? ou comme valeur que vous transmettez si c'est tout ce que cette structure contient. – Maslow

Répondre

3

Comme d'autres l'ont dit, vous devez utiliser la propriété Value à la valeur d'extraction. Cependant, System.Nullable<T> est immuable - la propriété Value est en lecture seule. Il va retourner une copie de la valeur, donc même si vous pourrait changer le champ, il ne ferait pas ce que vous voulez.

C'est en fait une bonne chose - les types de valeur devraient être immuable. Les structures mutables sont horribles - si le fait que Nullable<T> rend difficile l'utilisation de votre type vous pousse vers le bas de la route de l'immutabilité, c'est génial.

Faites votre champ en lecture seule, et ajoutez un constructeur pour vous laisser passer la valeur. Ensuite, au lieu d'essayer de modifier la valeur nullable, affectez une toute nouvelle valeur à la variable.

+0

Ah bizarre struct problèmes, une autre raison pour laquelle je n'aime pas les structures. – Maslow

+1

Bien que j'écrive rarement des structs moi-même, le problème est vraiment avec les structures * mutable * ici. –

+0

J'ai eu des structures mutables qui me mordaient avant, et comme je n'avais aucune idée de ce qui se passait ... j'ai changé la structure des mots en classe. et tout à coup tout mon code a fonctionné. J'ai donc abandonné les structures d'essai. – Maslow

-1

Lorsqu'un type est annulable que vous êtes censé être vérifier pour voir si elle a une valeur, alors l'accès à cette valeur que s'il y a une:

if(myNullableInstance.hasValue) 
myNullableInstance.value.myNullVar=1 
+0

Je reçois cette erreur lorsque j'essaie: "L'expression est une valeur et ne peut donc pas être la cible d'une affectation." – Pliskin

+0

Oui, il semble que ma connaissance des structures est presque inexistante depuis le passage à l'orientation de l'objet. Répondre à mes questions commentées sur le poste de base? – Maslow

+0

Aime le sarcasme. – Pliskin

0

Parce que la structure Nullable<T> expose la valeur sous-jacente via la propriété Value. Par conséquent, vous avez besoin:

myNullableInstance.Value.myNullVar = 1 
+0

Je reçois cette erreur lorsque j'essaie: "L'expression est une valeur et ne peut donc pas être la cible d'une affectation." – Pliskin

1

Comme d'autres réponses l'ont noté, vous pouvez accéder à la valeur interne d'un nullable avec .Value. Mais ils vous suggèrent de faire myNullableInstance.Value.myNullVar = 1 qui ne fonctionne pas.

C'est à cause de la façon dont les structures fonctionnent. Lorsque vous modifiez un membre d'une structure, une nouvelle instance de structure est créée. Vous ne pouvez pas faire cela dans ce cas car cela modifierait la propriété Value de la classe Nullable, ce qui ne peut pas être fait directement, car Value est ReadOnly.

Cela fonctionnerait bien:

Dim myInstance as myNullable 
myInstance.myNullVar = 1 
myNullableInstance = myInstance 
0

Il est logique que cela ne pas travail:

myNullableInstance.Value.myNullVar = 1 

Fondamentalement, vous seriez assignant à une copie de la structure qui a été renvoyée par la propriété Value.

Ce n'est pas vraiment un problème, car les structures sont généralement immutables comme bonne pratique. Vous pouvez contourner ce problème avec certaines affectations, mais comme d'autres l'ont signalé, vous devriez reconsidérer l'utilisation d'une classe à la place. De cette façon, vous n'avez pas non plus besoin de Nullable, car vous pouvez simplement utiliser une référence null.

0

Les structures nulles sont une douleur et il n'y a pas de bonnes raisons pour lesquelles Microsoft doit rendre les choses si difficiles. C'est fait de cette façon pour le rendre plus facile pour les auteurs du compilateur pas les utilisateurs du langage.

En fait, il n'y a pas de bonnes raisons pour lesquelles nous devons faire des types de références et des types de valeurs se comporter différemment.Microsoft essaie de cacher les pointeurs logiques (adresses) mais ça ne marche pas très bien car cela rend les choses plus difficiles et pas plus faciles. Chaque règle et restriction imposée à une langue rend les choses plus difficiles et se traduit par une inefficacité, des erreurs d'exécution et des coûts de développement plus élevés.

Nous ferions tous mieux si nous revenions aux pointeurs typés logiques. Ensuite, nous n'aurions pas besoin de mots fantaisistes comme immuable. (Immuable signifie immuable!)

Ma suggestion est d'abandonner les structures nulles et d'en faire une classe qui est toujours nulle.

Questions connexes