An "elegant" way of identifying a field?
- by Alix
Hi.
I'm writing a system that underlies programmer applications and that needs to detect their access to certain data. I can mostly do so with properties, like this:
public class NiceClass {
public int x { get; set; }
}
Then I go in and tweak the get and set accessors so that they handle the accesses appropriately. However this requires that the users (application programmers) define all of their data as properties.
If the users want to use pre-existing classes that have "normal" fields (as opposed to properties), I cannot detect those accesses. Example:
public class NotSoNiceClass {
public int y;
}
I cannot detect accesses to y. However, I want to allow the use of pre-existing classes. As a compromise the users are responsible for notifying me whenever an access to that kind of data occurs. For example:
NotSoNiceClass notSoNice;
...
Write(notSoNice.y, 0); // (as opposed to notSoNice.y = 0;)
Something like that. Believe me, I've researched this very thoroughly and even directly analysing the bytecode to detect accesses isn't reliable due to possible indirections, etc. I really do need the users to notify me.
And now my question: could you recommend an "elegant" way to perform these notifications? (Yes, I know this whole situation isn't "elegant" to begin with; I'm trying not to make it worse ;) ). How would you do it?
This is a problem for me because actually the situation is like this: I have the following class:
public class SemiNiceClass {
public NotSoNiceClass notSoNice { get; set; }
public int z { get; set; }
}
If the user wants to do this:
SemiNiceClass semiNice;
...
semiNice.notSoNice.y = 0;
They must instead do something like this:
semiNice.Write("notSoNice").y = 0;
Where Write will return a clone of notSoNice, which is what I wanted the set accessor to do anyway. However, using a string is pretty ugly: if later they refactor the field they'll have to go over their Write("notSoNice") accesses and change the string.
How can we identify the field? I can only think of strings, ints and enums (i.e., ints again). But:
We've already discussed the problem with strings.
Ints are a pain. They're even worse because the user needs to remember which int corresponds to which field. Refactoring is equally difficult.
Enums (such as NOT_SO_NICE and Z, i.e., the fields of SemiNiceClass) ease refactoring, but they require the user to write an enum per class (SemiNiceClass, etc), with a value per field of the class. It's annoying. I don't want them to hate me ;)
So why, I hear you ask, can we not do this (below)?
semiNice.Write(semiNice.notSoNice).y = 0;
Because I need to know what field is being accessed, and semiNice.notSoNice doesn't identify a field. It's the value of the field, not the field itself.
Sigh. I know this is ugly. Believe me ;)
I'll greatly appreciate suggestions.
Thanks in advance!
(Also, I couldn't come up with good tags for this question. Please let me know if you have better ideas, and I'll edit them)