I suspect Rocky aimed to solve this issue as much as possible within the framework.
I recall, in a speech he made at the .Net developers group in Minneapolis, he mentioned the use of PropertyHasChanged, for instance, has a couple overloads - one being with the string literal of the property name and one without. The one without involves using reflection in PropertyHasChanged, looking at the stacktrace, to determine which property "has changed" -- it removes the need for string literals and well, it saves Rocky the extra typing. One can use the string literal to avoid the reflection call to get the property. I find, for example, the code generation I uses the string literal - obviously no real room for error in this case (code gen).
I think what would be potentially useful (I guess I don't know if this is done currently or not) is that runtime exceptions get thrown if one adds a validation rule to a property or calls PropertyHasChanged for a property that doesn't exist. Perhaps what would be involved is a static cache of the available properties via reflection. At least in this case it would be an explicit error rather than some "hard-to-track" side effect of the validation rule not applied to the proper property or something to that effect.
But then you end up compromising how some people might use PropertyHasChanged and validation rules. There's nothing stopping the developer from using these constructs, to my knowledge, against a "custom property bag" or something to that effect. In other words, I might actually want to use string literals that don't apply to a particular compile-time property on the object.
Probably more rambling than anything...
Unfortunately you will not get away from having to be a programmer. You can automate many features, reflection and the stack trace method Rocky shows help this, but at some point you have to define the name for your property. Even with reflection, unless you are iterating the properties, you still have to identify the property you want.
How else would you identify the specific property except by name?
I share your concerns about using string literals. You could declare a constant variable for every property name in every class. I have tried this in a previous project and it worked out well. It is extra work, but if you are concerned about using string literals, it might be worth a try.
You can use a resource file as well but no matter what the approach, at some point you are going to have to map that "constant" to the string name of the property and make sure that it remains consistent with the actual name. Granted, having it as a constant or in a resource file centralizes any changes but in an application with 200+ classes (such as the one I am working on now)... Look at all the extra work you've added to the project. Just my opinion, but I don't see it being worth the trouble. Again, just my opinion.
What I would like to see is a way to integrate Intellisense into reflection. Then, instead of this.GetType().GetProperty("PropertyName"), you could refer to the property as this.GetType().PropertyName - or something like that. IMO, by accessing the property through the Type object, you'd be telling the CLR that you are accessing the PropertyInfo (or Descriptor depending on how they did it) rather than the instance value of the property. It would kinda work like resources now. To me, that's the cleanest way to accomplish it. Then, if you change the name of the property or remove it, you'd get a compile time error rather than having to wait for it to crash at runtime.
Just my thoughts...
Brian Criswell:You could take a page from Microsoft's book and attempt to add a code generation step into your build process. This step could look at a class and generate a partial class with a list of constants that corresponded to the property names. Just an idea...
I use enumerations for this purpose, and for database procedure names too. Just have to ToString() them. They also provide intellisense. ;)
Hadn't thought of doing a generator to create the enumeration in a partial class. That's an interesting idea.
david.wendelken:Brian Criswell:You could take a page from Microsoft's book and attempt to add a code generation step into your build process. This step could look at a class and generate a partial class with a list of constants that corresponded to the property names. Just an idea...I use enumerations for this purpose, and for database procedure names too. Just have to ToString() them. They also provide intellisense. ;)
Hadn't thought of doing a generator to create the enumeration in a partial class. That's an interesting idea.
This is interesting.
How do you create a form (using DataBinding), for example? The drag-and-drop in the designer assumes late bound string literals.
One direction I've seen taken is to develop a sort of framework around avoiding string literals. The application runtime is based on metadata. There is a custom forms designer that stores binding metadata rather than using codedom to write string literal databinding. One of the coding steps associated with compiling is to run the utility that churns through the metadata and verifies with reflection that it's all valid.
I've considered somewhat of a hybrid approach becuase I've discovered information that implies that (in theory at least) you can override the default serialization the forms designer uses such that instead of codedom generation it could save metadata.
The other thing I've considered is that it doesn't seem like a terribly daunting task to write a checker that could run through the entire application and verify the touchpoints between the layers ... that all the UI code referencing properties by string literals actually match an existing property, that the database load code in the BOs actually match the database schema, etc. Not a small task, of course, but not terribly difficult it seems to me. It think it would be natural in a code generation environment to include this as part of the generation process.
DansDreams:david.wendelken:Brian Criswell:You could take a page from Microsoft's book and attempt to add a code generation step into your build process. This step could look at a class and generate a partial class with a list of constants that corresponded to the property names. Just an idea...I use enumerations for this purpose, and for database procedure names too. Just have to ToString() them. They also provide intellisense. ;)
Hadn't thought of doing a generator to create the enumeration in a partial class. That's an interesting idea.
This is interesting.
How do you create a form (using DataBinding), for example? The drag-and-drop in the designer assumes late bound string literals.
The properties are still named with strings. Didn't get around that! It's just that all places where I would type in a string literal to reference them (i.e., that the compiler wouldn't naturally catch), I use an enumeration.
So, instead of :
CallSomeRoutine("MyPropertyName");
I have:
CallSomeRoutine(MyProperties.MyPropertyName.ToString());
I could still have a mis-match between the name in the enumeration and the name of the property, but that still reduces the problem to a much more manageable size.
DansDreams:The other thing I've considered is that it doesn't seem like a terribly daunting task to write a checker that could run through the entire application and verify the touchpoints between the layers ... that all the UI code referencing properties by string literals actually match an existing property, that the database load code in the BOs actually match the database schema, etc. Not a small task, of course, but not terribly difficult it seems to me. It think it would be natural in a code generation environment to include this as part of the generation process.
Yeah, I've wanted one of those too... Never had the time to sit down and write one.
Interestingly enough, this was an area of focus for VB 9, though the feature got deferred
But you were going to be able to do this:
Dim x As String = _obj.("GetName")
and this would have called the GetName method on _obj.
Since "GetName" is a literal string, it could have been a variable
Dim method As String = AppSettings("MethodToCall")
Dim x As String = _obj.(method)
That would've been so darn cool! Alas, it didn't make the cut. But perhaps VB 10 will have it, assuming Ruby/Python keep applying dynamic language pressures to the industry. VB already has a large percentage of the dynamic features, but it needs a couple more. And I don't know of any language that has quite this capability.
Copyright (c) Marimer LLC