 |
|
 |
This is creative and a good demonstration of some newer language features, but it strikes me as an overly complicated solution to a simple problem. You need to call code from the constructor anyway, so why not just set the defaults of your automatic properties there?
|
| Sign In·View Thread·PermaLink | 3.50/5 (2 votes) |
|
|
|
 |
|
 |
In my approach (same reflection things as in your article) I have a class that sets the default values. Classes where automatic properties are used have then to be inherited from this class.
public class AutomaticProperties { public virtual void InitDefaults(object o) { PropertyInfo[] propteryInfos = o.GetType().GetProperties( BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
foreach (PropertyInfo pi in propteryInfos) { if (pi.GetCustomAttributes(true).Length > 0) { object[] attributes = pi.GetCustomAttributes( typeof(DefaultValueAttribute), true);
if (attributes != null) { DefaultValueAttribute dva = attributes[0] as DefaultValueAttribute;
if (dva != null) pi.SetValue(o, dva.Value, null); } } } } public AutomaticProperties() { InitDefaults(this); } }
The constructor of the base class gets executed when an inherited class is initialized the code for the (inherited class) need no extension.
For instance:
public class MyClass : AutomaticProperties { [DefaultValue(true)] public bool boolWert { get; set; }
[DefaultValue(666)] public int intWert { get; set; }
[DefaultValue("Günther")] public string stringWert { get; set; } }
Regards Günther
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Good article, but as someone else said it's ridiculous to have to go to this trouble. 
My views are that I quite like automatic properties as they save a lot of typing and more often than not you don't have any extra code in the getter or setter. However the lack of initialization is very frustrating.
It's made worse because Microsoft have changed the prop snippet to create automatic properties instead of normal ones (note that you can add the old one back in). This means that if you need to initialize a property you either have to do it in the constructor or type the full syntax by hand which means it's even slower. Adding it in the constructor also defeats the point - these are meant to save typing!!!
And there is nothing on the refactor menu to let you change an automatic property into a full one.
I've created a request on Microsoft connect if you want to vote:
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=361647[^]
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
 |
Hi! I don't think its a good idea lose performance (using reflection and an extra method) just for an elegance in code. I think the best idea for default values in properties is to use a private variable the old fashion way: private [type] [var_name]; public [type] [prop_name] { get{return [var_name]} set{[var_name] = value} } Best regards, Jorge Desarrollo sitios web
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
I find this solution a bit over the top actually.
"Automatic properties" are used to save you time-typing for easy properties. If you need something specific you can't use them. You then have to use the old way.
The need to have a default value however is a common one.
My solution to this problem is actually simple and one I allready use right now in .NET2.0
class MyClass { public int MyProp {get; set;} public MyClass() { Init(); } private void Init() { MyProp = 5; } }
Instead of setting the default values through attributes, I just set them in code in a method (Init). You can call this method then in all your c'tors.
It's the same amount of typing. Just simpler (in my opinion).
As to the inherited classes. I don't really care about their properties in my base-class. The inherited class should know how to initialise itself during creation, not it's base class
Best regards, Ike
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
While I agree with you there are 2 things to consider:
1. constructor's code will not be next to the property, so if you have a really long list of properties you should scroll up and down to see their default values 2. the setter will be invoked, hence in a class that inherited your base class it may behave differently (which is actually the case with the solution in this article too).
Ideally MS will enhance the syntax to something like this:
public int MyProp { get; set; default=123; }
But until then I too believe a constructor is the best solution especially considering the performance impact when using reflection...
Regards, Nick
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
In my period of developing application, the default values (according to business domian) at best can be set out of the codes. Otherwise, each time users change the requirement you must go into the cluttering code to interpolate attribute.
Take nothing on looks; take everything on evidence. - Charles Dickens
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I'd do it differently... but no one here should be surprised about that.
I'd eliminate some of the local variables by using foreach rather than for.
I'd eliminate the extra check for attributes.
I might also add type checking to be sure the property can be set to the value.
Also, if you instantiate a large number of a particular type and then perform InitDefaults on each, you'll hit Reflection a number of times, at considerable cost, always getting the same results, so I suggest caching the results to improve performance.
public static void InitDefaults ( this object o ) { foreach ( System.Reflection.PropertyInfo prop in o.GetType().GetProperties ( System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Static ) ) { foreach ( System.ComponentModel.DefaultValueAttribute dva in prop.GetCustomAttributes ( typeof(System.ComponentModel.DefaultValueAttribute) , true ) ) { if ( o.GetType().IsAssignableFrom ( dva.Value.GetType() ) ) { prop.SetValue ( o , dva.Value , null ) ; } } } }
(Well, that compiles, but I'm not sure the type check will work, I haven't tested it.)
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
 |
if ( o.GetType().IsAssignableFrom ( dva.Value.GetType() ) ) { prop.SetValue ( o , dva.Value , null ) ; }
How come you did't write almost every word in separate line, like the rest of your code..
>I'd eliminate some of the local variables by using foreach rather than for. foreach is proven to be less efficient.
life is study!!!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Aw, crap, you're right! I forgot to split up the call to SetValue!
Seishin# wrote: foreach is proven to be less efficient.
Do you have numbers?
foreach is more readable, so unless it's much less efficient, I'll use it.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Seishin# wrote: foreach is proven to be less efficient.
Here are some numbers; summing the elements of a 100000-element array of longs 100000 times:
for takes 00:01:40.6127095
foreach takes 00:01:46.2636235
(Pentium Dual, 1.8 GHz, 1GB RAM, WinXP)
Although that's about a 5% difference I don't consider it to be significant.
Me: "Saving five seconds over a minute-and-a-half? Big fat hairy deal."
I'll gladly take the readability of foreach in a case like this.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
He says:
" foreach copies the current array to a new one "
which is ridiculous. And he doesn't give any numbers.
It's also possible that the enumerator for arrays has been improved since he wrote that.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
well, his article isn't one of the best, but I read one here at CP that gave numbers.. and the numbers spoke to me.. unfortunatelly I can't seem to find it now.. when I do I'll surely post it here for you.
life is study!!!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
I'm not arguing the merit of your article, but instead am arguing the merit of automatic properties. Rather, I'm commenting on the value of automatic properties, especially given that you can't set default values without adding code. So...
I'm way old school, so it looks to me like it obfuscates the code. The following
private int m_myValue = 1;
public int MyValue { get { return m_myValue; } set { m_myValue = value; } }
is much easier to maintain than this:
public MyValue { get; set; }
Just because you *can* hide the minutia doesn't mean you should. Next thing you know, .net will ooze into the hell that is "typeless languages".
What they should really do is give us a way to add properties through the Class View pane. All we should have to do is specify the name of the data member, select accessibility and type from drop-down lists, and check a couple of boxes regarding the presence of set and get. The code should be automatically added for us based on what we select. THAT would be a productivity enhancement.
"Why don't you tie a kerosene-soaked rag around your ankles so the ants won't climb up and eat your candy ass..." - Dale Earnhardt, 1997 ----- "...the staggering layers of obscenity in your statement make it a work of art on so many levels." - Jason Jystad, 10/26/2001
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
 |
John Simmons / outlaw programmer wrote: add properties through the Class View
That would be an IDE feature, not a language feature.
P.S. But, yeah, automatic properties and extension methods both.
modified on Wednesday, May 14, 2008 7:50 PM
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I've blogged about this, calling automatic properties the "lamest addition" to C# (http://wekempf.spaces.live.com/blog/cns!D18C3EC06EA971CF!234.entry[^]).
I can't agree about extension methods. They are vital to LINQ, if for nothing else. There's also a lot of very nice things that can be accomplished with them that have extremely sub-optimal solutions without them.
As for this particular article... I don't find it useful. The extra code required here reduces the little productivity benefit you get from automatic properties. Worse, you suffer performance wise from this. If you are going to use automatic properties, what's wrong with initializing them in the constructor?
public class Foo { public Foo() { Bar = string.Empty; }
public string Bar { get; set; } }
William E. Kempf
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
William E. Kempf wrote: They are vital to LINQ
I don't use LINQ (I've only seen it in a demo at the {launch} event), but knowing that some here do I decided not to add var to my post.
William E. Kempf wrote: extremely sub-optimal solutions without them
I am interested in seeing one (that doesn't use LINQ).
William E. Kempf wrote: what's wrong with initializing them in the constructor?
Indeed; wouldn't that be the logical place to call InitDefaults anyway?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
PIEBALDconsult wrote: William E. Kempf wrote: extremely sub-optimal solutions without them
I am interested in seeing one (that doesn't use LINQ).
A simple example is providing method overloads for interfaces. The options without extension methods are to put the overloads in the interface, requiring every implementation to have to implement them (and possibly even change the intended contract), or to use static helper methods in some class. While the latter *IS* exactly what you're doing with extension methods, the complexity for consumers of the API has been drastically reduced.
That's just one example. There's a lot of other examples in the wild. For instance, fluent interfaces are much easier to achieve using extension methods.
William E. Kempf
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
William E. Kempf wrote: The options without extension methods are to put the overloads in the interface, requiring every implementation to have to implement them (and possibly even change the intended contract),
Well, my understanding is that extension methods are for when one doesn't have the ability to modify the class/interface. If you do have control over the class/interface, and it makes sense to add the method, then go right ahead and add it; if not, why use an extension method to make it look like you did?
There are two things I don't like about extension methods: They require a using directive. When the code is printed out or posted online, or otherwise not displayed in VS, I can't tell that a particular method is an extension method.
Oh, and what if they who do control the class/interface later add a method that matches the extension method but does something else? (I'll have to check that out myself.)
At any rate, I'm still not sold.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
PIEBALDconsult wrote: Well, my understanding is that extension methods are for when one doesn't have the ability to modify the class/interface. If you do have control over the class/interface, and it makes sense to add the method, then go right ahead and add it; if not, why use an extension method to make it look like you did?
With a class, that's absolutely correct. I explained why it's not ideal with an interface. "Just adding it" to the interface means that every implementation has to provide an implementation that should be THE EXACT SAME implementation in every case.
PIEBALDconsult wrote: There are two things I don't like about extension methods: They require a using directive.
So does everything else. In all of the use cases I gave, however, the extension method resides in the SAME namespace, so no extra using is required.
I will give you a partial point (maybe an 1/8 point) here. The IDE automates adding the using most of the time, but with extension methods it can't. This causes me a little grief from time to time with LINQ. It's not the end of the world, however.
PIEBALDconsult wrote: When the code is printed out or posted online, or otherwise not displayed in VS, I can't tell that a particular method is an extension method.
The classic counter argument, and it holds NO water with me. If I'm reading code, not maintaining it, why would I care? If I'm maintaining, I'm going to be using developer tools that will reveal what I need to know.
PIEBALDconsult wrote: Oh, and what if they who do control the class/interface later add a method that matches the extension method but does something else? (I'll have to check that out myself.)
The non-extension method will be called.
William E. Kempf
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
You can identify extension methods because the signature starts with "this" ie: ExtensionName(this object o)
-Steven
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
That's not the argument. Given this:
Foo foo = new Foo(); foo.Bar();
Is Bar() a member of Foo, or an extension method?
Again, though, I don't buy this argument. If I'm reading code, why would I care? If I'm maintaining code, my tools will tell me the answer.
William E. Kempf
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |