3

In a C# application I am working on I have a very long identifier as follows:-

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

Whenever I to reference this object it's an absolute nightmare, and unfortunately I do need to reference it a lot:-

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.

I want to update this code using a far smaller alias of some kind, the problem is however that I want to change the underlying reference, and have the alias update also without explicitly updating the alias.

Currently if I do the following:-

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);

It will output "hello". What I want to achieve is something like the following:-

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);

Which would output "world" as required.

I believe you can achieve something like this using unsafe code in C#, however I cannot do that, I have to use safe code only.

Does anybody have any ideas how I might achieve this?

Please Note: This question is not about strings being immutable, I know they are - in fact I assumed they are for the purposes of the question. It might perhaps be simpler if I used some other type... so when I assign "hello" to a then "world" to a, I am instantiating different objects on each occasion, hence my stored reference to a becomes invalid after re-assignment.

ljs
  • 37,275
  • 36
  • 106
  • 124

3 Answers3

5

One way out is to use one or a pair of lambdas.

For example:

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

Now, you can use getter and setter to read and write the long identifier.

However, since your dots are member accessors, the easiest way of going about it is to take a reference to the immediate parent, like so:

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

This is good practice in any case, as a long dotted expression like this is a violation of the Law of Demeter, which inhibits the flexibility of the codebase - it requires too much information in too many places.

Barry Kelly
  • 41,404
  • 5
  • 117
  • 189
  • That is very nice Barry you absolute life-saver! – ljs Nov 26 '08 at 11:56
  • If so, then all you need do is keep a reference to huge, and dereference to get the "a" member every time. – Barry Kelly Nov 26 '08 at 13:00
  • Barry, what if I then reassign bar? It won't hold then. – ljs Nov 26 '08 at 14:02
  • That's an excellent point about the law of Demeter, thank you, will take a look at the architecture! – ljs Nov 26 '08 at 14:16
  • If you reassign to bar, then you'll break it, yes. However, that will break the lambda approach too - at best, the lambda will capture the root of the expression (an implicit "this" if any, or "foo" otherwise). Reassigning foo's "bar" property will break the reference in the same way. – Barry Kelly Nov 26 '08 at 14:47
  • The lambda approach should work surely? Won't it effectively act as a macro in this instance? – ljs Nov 26 '08 at 16:55
  • Sorry, kronoz - I was assuming that you wanted reference semantics like a pointer to the underlying string field would give you. Yes, it will act like a function, but importantly, not like a reference to a reference. – Barry Kelly Nov 26 '08 at 17:19
1

I would use namespace alias.

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

then inside your method you just had to type: myAlias.huge.a = "hello";

Sergio
  • 8,125
  • 10
  • 46
  • 77
  • Isn't the using statement simply for type aliasing? – ljs Nov 26 '08 at 14:03
  • you can only define namespaces with using. As the problem presented was a long long line of code, i guess this would work ;) – Sergio Dec 05 '08 at 10:16
0

First thing. I would rethink your architecture. That seems way too complicated! :)

Anyways, let's get to business.

Strings are immutable in .NET and that's your problem. When you change the object's property, you are creating a new string on memory and pointing there with the object's property. However, this does not change your string variable (why should it?). The variable hasn't changed, so it keeps pointing to the previous string.

That's the problem, now to the solution. I'd suggest creating a reference to the object that contains the string, just one level above, like this: foo.bar.bwah.blah.whatever.very.very.huge.a = "hello"; Huge huge = foo.bar.bwah.blah.whatever.very.very.huge; huge.a = "foo!";

Hope it helps! :)

rgargente
  • 1,821
  • 2
  • 19
  • 30
  • Firstly this isn't about strings, I used that example on the assumption strings are immutable so that I could make my point more clearly! That was perhaps not the best choice! :-) Yes, but what if I want to re-assign the 'huge' object? also if say bwah was re-assigned we'd be getting wrong also. – ljs Nov 26 '08 at 12:09
  • Oh and I don't think it's an architecture problem! Though perhaps it could be better constructed; The actual code is only say 3-4 fields deep, only the names are rather long. I think it's very possible for this problem to come up in a well-formed architecture. – ljs Nov 26 '08 at 12:10
  • I see kronoz, it's true. Now I see your point. However, I think it's not worth it to complicate the code too much just to write shorter names. But maybe it's just me! Anyways, the question is interesting, I will keep an eye on it and post again if I come up with something! – rgargente Nov 26 '08 at 12:25