2011-08-19 5 views
3

J'ai une variable de type d'objet (contrôle .Tag) que je dois jeter à un type structuré, et changer un membre Ceci est un exemple artificiel mais représentatif.Comment puis-je faire du casting de style C dans VB.NET?

Public Structure struct_COLOURS 
    Dim ILikeRed as boolean 
    Dim ILikeGreen as boolean 
End Structure 

Dim AnObject as Object = (some source that is struct_COLOURS) 

DirectCast(AnObject, struct_COLOURS).ILikeRed = True ' This is not valid syntax?! 

Je ne me rappelle pas mon syntaxe C très bien, mais ce serait quelque chose comme ceci:

(struct_COLOURS*)AnObject->ILikeRed = true; 

le point est que je peux jeter un objet à quelque chose et mettre les membres de la distribution résultant. Il semble que DirectCast soit réellement une fonction et qu'elle ne soit pas interprétée comme je l'interpréterais.

Bizarrement, si vous voulez seulement récupérer une valeur de membre, vous pouvez utiliser DirectCast:

dim YummyRed AS Boolean = DirectCast(AnObject, struct_COLOURS).ILikeRed 

est très bien!

Si je ne peux pas lancer comme je le souhaite, et que je ne peux pas modifier la propriété Tag (donc ne le suggérez pas, ce n'est pas une option) pour stocker ces structures, quel est le moyen le plus rapide?

Répondre

7

Il semble que DirectCast soit réellement une fonction et ne fonctionne pas comme je l'interpréterais.

Non, ce qui ne va pas: DirectCast est pas une méthode, il est une véritable construction de langage, comme un plâtre en C.

Cependant, si vous stockez une structure (= type de valeur) dans un objet, il obtient boxed et, par conséquent, copié. Cela provoque le problème ici: vous essayez de modifier une copie, pas l'original, objet en boîte.

Ainsi, afin de changer un membre d'un objet de type de valeur en boîte, vous devez copier l'objet, modifier sa valeur, et recopiez-:

Dim tmp = DirectCast(AnObject, struct_COLOURS) 
tmp.ILikeRed = True 
AnObject = tmp 

Soit dit en passant, est la même chose en C#, malgré la similitude superficielle avec la syntaxe de distribution C.

+0

Comment placer quelque chose qui n'est pas encadré mais structuré? –

+0

OK. Que dirais-je de stocker toutes mes structures dans un tableau typé séparé et le Tag contient juste l'index? La relation serait cohérente pour la durée de vie des contrôles. Je devrais changer beaucoup de code, mais déplacer les données hors de l'objet tag est un objectif à plus long terme de toute façon, mais pas celui que je voulais aborder maintenant. –

+0

@Mark Les types de valeur sont * toujours * encadrés lorsqu'ils sont stockés dans un objet, il n'y a aucun moyen de contourner cela. Stocker l'index dans un tableau global peut être une solution acceptable dans votre cas. –

-2

Voilà comment vous devriez jeter - CTYPE:

Dim myColor As Object = Nothing 
     Dim color As Color = CType(myColor, Color) 
     color.Name = "red" 

Pourquoi un struct et non une classe?

+2

Non, c'est faux. Tout d'abord, cela n'a rien à voir avec le problème. Deuxièmement, 'CType' n'est pas préféré ici.En fait, 'DirectCast' devrait toujours être préféré car il est plus restrictif et permet une meilleure vérification de type. Troisièmement, votre code ne suit pas le bon style en déclarant 'myColor' sans l'initialiser immédiatement. –

+0

Une classe est exagérée si tout ce que vous voulez faire est de stocker une collection de variables de manière organisée. Une structure est, ou devrait être, extrêmement efficace parce que c'est juste un morceau de mémoire qui est lu d'une certaine manière. D'ailleurs, une classe ne devrait-elle pas être coulée de la même manière? –