2008-11-26 8 views
2

Dans une application C# Je travaille sur J'ai un identifiant très longtemps comme suit: -SÛR pointeur vers un pointeur (bien référence à une référence) en C#

foo.bar.bwah.blah.whatever.very.very.huge 

Chaque fois que je faire référence à cet objet, il est un cauchemar absolu, et, malheureusement, je ne faut référencer beaucoup: -

var something = foo.bar.bwah.blah.whatever.very.very.huge.a; 
var somethingElse = foo.bar.bwah.blah.whatever.very.very.huge.b; 
foo.bar.bwah.blah.whatever.very.very.huge.c = 12; 

etc., etc.

Je veux mettre à jour ce code en utilisant un alias beaucoup plus petit de quelque sorte, le problème est cependant e Je veux changer la référence sous-jacente et mettre à jour l'alias sans mettre explicitement à jour l'alias.

Actuellement, si je fais ce qui suit: -

foo.bar.bwah.blah.whatever.very.very.huge.a = "hello"; 
string shorter = foo.bar.bwah.blah.whatever.very.very.huge.a; 
foo.bar.bwah.blah.whatever.very.very.huge.a = "world"; 
Console.WriteLine(shorter); 

Il sortira "bonjour". Ce que je veux réaliser est quelque chose comme ce qui suit: -

foo.bar.bwah.blah.whatever.very.very.huge.a = "hello"; 
string** shorterPointer = &foo.bar.bwah.blah.whatever.very.very.huge.a; 
foo.bar.bwah.blah.whatever.very.very.huge.a = "world"; 
Console.WriteLine(**shorter); 

Ce qui produirait "monde" comme requis.

Je crois que vous pouvez réaliser quelque chose comme ça en utilisant du code dangereux en C#, mais je ne peux pas le faire , je dois utiliser du code de sécurité seulement.

Est-ce que quelqu'un a des idées sur comment je pourrais y parvenir?

S'il vous plaît noter: Cette question ne porte pas sur les chaînes étant immuable, je sais qu'ils sont - en fait, je suppose qu'ils sont aux fins de la question. Cela pourrait peut-être être plus simple si j'utilisais un autre type ... alors quand j'attribue "bonjour" à un "monde" à un, je suis instanciation de différents objets à chaque fois, donc ma référence stockée à un devient invalide après réaffectation

Répondre

5

Une solution consiste à utiliser un ou deux lambdas.

Par exemple:

Func<string> getter =() => blah_de_blah; 
Action<string> setter = x => blah_de_blah = x; 

Maintenant, vous pouvez utiliser getter et setter pour lire et écrire l'identifiant long.

Cependant, étant donné que vos points sont accesseurs membres, la meilleure façon d'aller à ce sujet est de prendre une référence au parent immédiat, comme ceci:

var myHuge = foo.bar.bwah.blah.whatever.very.very.huge; 
// now access myHuge.a everywhere 

Cette pratique est bonne dans tous les cas, comme Une longue expression pointillée comme celle-ci est une violation de la Law of Demeter, ce qui inhibe la flexibilité de la base de code - elle nécessite trop d'informations dans trop d'endroits.

+0

C'est très agréable Barry vous sauver la vie absolue! – ljs

+0

Les points * sont * des symboles d'accès membres !!! Mais votre technique fonctionnera indépendamment. – ljs

+0

Si oui, alors tout ce que vous devez faire est de garder une référence à l'énorme, et déréférencer pour obtenir le "un" membre à chaque fois. –

0

Première chose. Je repenserais ton architecture. Cela semble beaucoup trop compliqué! :)

De toute façon, passons aux choses sérieuses.

Les chaînes sont immuables dans .NET et c'est votre problème. Lorsque vous modifiez la propriété de l'objet, vous créez une nouvelle chaîne dans la mémoire et pointez là avec la propriété de l'objet.Cependant, cela ne change pas votre variable de chaîne (pourquoi devrait-elle?). La variable n'a pas changé, elle continue de pointer vers la chaîne précédente.

C'est le problème, maintenant à la solution. Je suggère de créer une référence à l'objet qui contient la chaîne, juste un niveau au-dessus, comme ceci: foo.bar.bwah.blah.whatever.very.very.huge.a = "hello"; énorme énorme = foo.bar.bwah.blah.whatever.very.very.huge; énorme.a = "foo!";

J'espère que ça aide! :)

+0

Tout d'abord, il ne s'agit pas de cordes, j'ai utilisé cet exemple sur l'hypothèse que les cordes sont immuables pour que je puisse mieux faire valoir mon point de vue! Ce n'était peut-être pas le meilleur choix! :-) Oui, mais que se passe-t-il si je veux réaffecter l'objet 'énorme'? aussi si on dit que bwah a été réaffecté, on se trompe aussi. – ljs

+0

Oh et je ne pense pas que ce soit un problème d'architecture! Bien que peut-être il pourrait être mieux construit; Le code actuel dit seulement 3-4 champs profonds, seuls les noms sont plutôt longs. Je pense qu'il est très possible que ce problème apparaisse dans une architecture bien formée. – ljs

+0

Je vois kronoz, c'est vrai. Maintenant, je vois votre point. Cependant, je pense que ça ne vaut pas la peine de trop compliquer le code pour écrire des noms plus courts. Mais peut-être que c'est juste moi! Quoi qu'il en soit, la question est intéressante, je vais garder un oeil dessus et poster encore si je viens avec quelque chose! – rgargente

1

J'utiliserais un alias d'espace de noms.

using myAlias = foo.bar.bwah.blah.whatever.very.very 

puis à l'intérieur de votre méthode que vous venez à taper: myAlias.huge.a = "hello";

+0

L'instruction using n'est-elle pas simplement utilisée pour l'aliasing de type? – ljs

+0

vous pouvez uniquement définir des espaces de noms à l'aide. Comme le problème présenté était une longue ligne de code, je suppose que cela fonctionnerait;) – Sergio

Questions connexes