- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
2. ???
3. Profit!
Admin
I think its a way to get assignment overloading in c#.
Contact a( somekey );
Contact b;
b.contact = a;
b = b.contact; // This could, if he's really diabolical, be in LoadFromContact()
But... I'm pretty lost really.
Admin
Admin
I don't write Java, but the concept remains, thusly, and not just for OO languages:
Getters and setters define an interface. A fixed interface. Whether an accessor is optimised out by the runtime / compiler to be a straight variable/property fetch, or whether it involves 20 round trips to the database to get / set your return value doesn't matter to the person using it. If the internal implementation changes to involve 20 round trips to the database, it doesn't matter as long as the contract as to how that accessor is to be used doesn't change.
So, what are the benefits and costs of using accessors?
+ You have a stable interface to program to
+ In most cases, direct accessors will be optimised down to direct variable / property access anyway
+ Maintenance is easy, as everything is decoupled. Wanna change a class' internal implementation? Piece of cake.
- You might have do some minimal work to set up boilerplate accessors
- You might see some minimal performance hit if accessors aren't optimised out
And likewise for not using accessors
+ You might see some performance increase
+ You won't have to bother setting up boilerplate accessors, you lazy bastard
- You have tightly coupled the interface of your class to its internal implementation, thus creating a maintenance nightmare
You're right, of course, that 90% of accessors are direct, and probably 90% of those will never change over an application's lifetime. I've done maintenance work on code written assuming this, and I can tell you that it's not fun. Having to change direct access to variables (sometimes through pointers, sometimes not) into accessor calls in a C++ project comprising millions of lines of mostly undocumented code is painful.
The only time you should be directly accessing variables on an object is within that object itself. Everything else goes through its interface unless there is a very good reason not to; I can't think of one of those at the moment (but it's early and I've not had my 3rd coffee yet).
If you work for me and insist on using direct access, you aren't going to work for me for long. Direct access is a lack of rigour. And lazy. I don't employ people who work that way.
Simon
Admin
Hey, you know, I coulda sworn the title of the page was "The Daily WTF?" and not "The Daily Post Where Everybody Tries To Guess The Appropriate Useage Of This Code and Whether Or Not It Was, In Fact, Properly Used."
Admin
Admin
I heard that in .NET, you can start with a public member variable and later hide it behind property accessors, without breaking existing code. I haven't verified this myself. There may be corner cases which I miss if I test it, so I was wondering: anyone know for sure whether this is true?
Rik
Admin
The url only makes me want to flame harder!
Admin
Kernel developers tend to reverse the meaning of get/set, read/write, etc. I'm sure this is just some kernel hacking to make managing contacts more efficient!
Admin
You must be new here...
Admin
Admin
Ehm, you're new here, right?
Admin
Argh, I _knew_ I should have read all replies before replying myself... *makes note to self*
Admin
<FONT size=5>As a matter of fact, HE IS !!!</FONT>
Admin
Please ignore - just playing with formatting...
<center>Admin
and that was a bust....
Admin
Interesting - if you click on 'quote', it renders it correctly in the html editor, but not in the forum itself. Um, WTF???
Admin
If you look at it from a very sick point of view (for some reason, it seems like I have a talent to do that), it just makes sense this way.
Let's say you want to save a value to the database. To do that, you have to GET it from the internal field. Likewise, after you load it from the database, you SET the value of the internal field. So, in an incredibly twisted attempt to do it kind-of-OO, the author decided that GET and saving are one action, while SET and load are the other one.
Admin
You're completely missing the point of getters/setters. If all you want to do is set a variable, great, maybe that could be made public. But then six months down the line you find that people haven't been setting that variable correctly. Clearly some validation needs to be added.
This is where a setter comes in. But, see, you're now going to add a GetContact (or whatever) function, right? Ok, maybe that's the best way to go, but remember that people have just been setting a variable up to now, and they now have to hunt through their code to find all the references.
If you'd been sensible in the first place, you would have made your variable private, and exposed a public property. In that case, all you have to do is change the setter. Everyone else can just carry on merrily without having to hunt through their code for references to that variable. The only people who need to change anything are the people who caysed the bugs in the first place.
There are lots of other good examples which I'll leave you to figure out on your own.
Admin
In C#, couldn't you just start with a public field and later (when you need validations, side effects etc.) replace the field with a property of the same name (and give the field a different name and make it private)?
Admin
In C#, couldn't you just start with a public field and later (when you need validations, side effects etc.) replace the field with a property of the same name (and give the field a different name and make it private)?
Yes, but thats piss-poor practice and sheer laziness on the part of the developer. Your naming conventions and thus code readability and understandibility (made up word?) for maintenance purposes by others would be reduced. Is that a private member variable or is it a property accessor? Dunno, lets go back to the definition and see. Oh OK, that'll be fun and a good use of my time :-) Just because you can do something doesn't mean that you should - look at the wonderful examples all around us here!
Admin
Honestly, does it really help to know if xxx is a public member variable or a property? Even if I know that it is a property, I still cannot say if it has side effects, does validation etc. or if does nothing but get { return _xxx; } set{_xxx=value;}
Admin
this is very bad practice, please stop doing it.
Admin
Dunno about .NET, but it wouldn't surprise me - it's fairly common practice in other languages / frameworks.
In Ruby, for example, I might do this:
Which will automatically create public getters and setters for variable 'foo', without me having to bother writing any code. Later I might decide that the setter needs to change in order to do some specific checking, all I have to do is this:
In Cocoa / OpenStep in ObjC using key-value coding it's all done automatically, so I define a variable @foo in my class, then use [instance setValue:value forKey:@"foo"] to set it and [instance valueForKey:@"foo"] to access it. If I haven't defined accessors, it's done using a search order as defined here :http://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/SearchImplementation.html#//apple_ref/doc/uid/20000955-CJBBBFFA
Typically, one uses -takeStoredValue:forKey: and -storedValueForKey: internally within your class instead of explicitly using the instance variables, allowing you to decouple a class from its own implementation (it may seem mad, but given that you can add methods to a class 'on the fly' as it were, this is actually pretty good practice). It's a little more work than using accessors directly, but it makes loosely coupled user interfaces a dream to program.
You can also get and set stuff via key paths (for example, I might call [instance valueForKey:@"foo.bar"] which would get the 'bar' attribute of the 'foo' attribute of 'instance' etc), and set stuff 'en masse' using hashes / dictionaries but the underlying mechanism is the same.
It's also nice that there's a 'catchall' -setValue:ForUndefinedKey: and -valueForUndefinedKey: which means you can massacre the public interface if you need and still have legacy code work with your class, or delegate certain keys to other objects, etc.
Yeah, I like ObjC. Ruby is pretty sweet, too.
Simon
Admin
Yay! CommunityServer FTW!
Admin
Just a thought:
The SaveToDatabase and LoadFromContact are, I guess, private functions of the class.
SaveToDatabase does some formatting to the data so that fits nicely in to the DB (phonenumber formatting, address - don't ask me) and returns the newly-formatted version. Heck, it might even check if saving to DB is really needed and do nothing but return the correctly formatted version if not. So, the getter only ensures that the data has been properly formatted and returns it. Bad naming for the Save-func at most.
The setter calls a method that copies a contact to this one (deep/shallow/anything, just the right way). Ok, that code could/should have been written here, but if it's needed from elsewhere as well, isn't it just the same? One extra step in call stack, yea?
Can be interpreted as (almost) WTF-free, or then I'm completely wrong. You tell me (I know you will if I'm wrong :)
Admin
If I'm writing code that uses your class, no it doesn't help me, except to give all your exposed members a consistent naming standard. For a contact class, which looks best?
or
Inside the class, it means you can make sure that it's clear where the properties tie to their respective variables:
Of course, the whole point of getters/setters in the first place is to make getting/setting them more intelligent, so
Admin
That ended up a little mashed - imagine the two class Contact definitions in the second example are merged.
Admin
So now you have to go through your class and change all your internal references to that field otherwise it will be going through the properties (which is not the best idea since some of the validation may cause problem internaly). Instead of saving time, you now have to spend extra time making sure you got everything corrected! Multiply that by even 3 or 4 fields in a class that takes up 500+ lines, and lazyness has just cost you a bundle of time (which means <FONT color=#ff0000>-$$$</FONT> in your project).
Erik of Ekedahl
Admin
I see your point. Because of the naming conventions, I would have to decide whether I want the member variable name look like a property or have the property named like a variable; both alternatives are ugly.
Well, this is exactly the kind of more-or-less meaningless code I'd rather want to avoid. I think it might me a good idea to put that into a
so you don't have to read it when you browse the program
Admin
You must be joking. Really. First, I do a search-and-replace to change all internal references to the new name of the variable. Estimated time to do that: 8 seconds. Then I introduce the property.
Admin
Or you use any IDE that includes refactoring (SharpDevelop, VS2005 or VS2003 with the "Refactoring" tools, and there are probably others too), right-click on the property and choose "Rename"...
Admin
I should say, do that on the variable. Then introduce the property, as ammoQ said.
Admin
I'm afraid the refactoring rools would change the external references to that variable, too, but this is not what I want.
Admin
You may be right, but if I had a dollar for every time someone here claims that a practice is "very bad" with no justification at all, I'd be up about uh, $2 by now.
Why is it bad? What's the difference? Where's the potential for error?
You may be right, but I'm not certain of it. You are certain, but you can be certain and wrong, so I think I'm ahead here.
PS: forum owners, fix your balsted CAPTCHA already. It always fails the first time.
Admin
What's really bad about the practice of accessing a database in a property like this (assuming this is C#) is that if you're in debug mode and stepping through the code, and you hold your cursor over an object's property (like this one), the value of the property will be shown as a tooltip, and the actual code in the property will be executed right then, quite unexpectedly, possibly making you want to strangle the co-worker who wrote it.
WHY THE F&&#$* DOESN'T CAPTCHA EVER WORK THE FIRST TIME????
Admin
Oh my goodness! Finally, someone else who has read those articles!
I thought I was the only one calling shenanigans on the propagation of the Java Bean Spec into the OO way of doing things!
I recently attempted to make life easier by automagically wrapping 6 or 7 parameters into a struct and passing that into a bunch of dispatch methods in Strutsland. I had to fend off a guy who said, "Hey Man! You can't expose properties like that! We need to wrap them with getters/setters!" Sometimes I find the people I work with a real PITA.
Admin
Indeed, you should do something like that.
Admin
Any language with at least remotely well thought off properties allows you to painlessly and transparently switch raw members access and property-protected members access. Or it always hides raw members behind basic, generic, direct get/set default accessors (when you ask the langage to expose them, that is. Imagine Java automagically creating direct getters&setters every time you define a field "public" instead of giving the outside access to the field itself).
The corollary is that .Net's implementation of properties is a fucking piece of crap.
Oh well, at least you can specify properties in interfaces, see, it could have been even worse...
You heard wrong, swapping raw members and properties will break everything, and the fact that MS requires programmers to CamelCase properties to clearly separate them from raw members access in their style guidelines emphasize the sheer stupidity of the implementation.
The only reason why C# has properties is to please the Marketroids ("hey, look, C# has properties and java doesn't, it has only ugly getters and setters methods!" you hear them shriek), they're no better than java's getters and setters and only very slightly less verbose.
No, they're handled very differently, and you can't specify a field in an interface (while you can specify a property), and you aren't supposed to name them the same way at all (per MS' style guidelines), ...
The point is that you don't care.
The very point of properties, the original one, the basic one, is that it allows you to _change your mind_.
No design is perfect upfront, no interface is done right the very first time it's written or specified, likewise for member access protection. If you want to be able to change your mind, you've either got to use The Java Way, pay a heavy price upfront, pile dozens of lines of useless, cluttered, annoying, automatically generated getters and setters (because no one writes getters and setters manually right?), or use an ancient, arcane knowledge, that cometh from the land of Smalltalk and was revived by the Gem and the Snake: just expose the member already if the interface needs the info, and hide it behind validation if required.
And to the one saying that the (just added) validation/whatever from properties access may break the inner workings of the class when used internally I answer: duh? do you mean that an external object could fetch the data from the getter (modified internally in a way that would be broken by a property/setter access), then send it back unmodified through the setter, and get an error because the inner workings of your objects put it's internal data in states it should never be in? (that's kind-of the point of data validation you know). I think your objects have bigger problems than properties.
Admin
Dear God, and to think I almost used Java at one point. Tell me they don't do that, please. Tell me they wouldn't be so f*cking stupid?
Ok, it's not quite as bad as that, but there are definitely cons to it as well as pros. Ruby does the same thing, and while I love Ruby for small projects, for larger things C#'s my thing. This is because Ruby goes off and does a load of things behind the scenes that I'm really better at making decisions about, to be frank. Datatypes is one of those things (Ruby is dynamically typed), whether to create accessors is another (though Ruby is sensible enough to actually let me decide whether or not to create an accessor and not just assume). Memory management is something the compiler is better at than me, so I'm happy to leave that kind of thing alone.
In a small project that I want to get done quickly, this is fine. But there comes a critical size (and I'm not sure what it is) where having to keep track of what I'm doing as well as what the compiler is doing behind my back becomes a big hindrance and a language where I have to specify everything becomes a whole lot better. What datatype is that variable? In Ruby I have to go and find where it came from. In C# I can just ask the IDE, or with a line of code ask the variable itself.
So don't go off on one just because one language requires a little more work to get small things done - when you put 'em all together, you'll be thankful that you did the work.
Oh, dear, you're one of those. I assume you were present at that Marketroid meeting and therefore have a f*cking clue what was said in it?
Admin
No, you can't do that. Properties and fields are "source compatible" but not binary compatible. IOTW, if you change a field to a property you have to recompile everything that uses that field.
That might be ok for a small project, but if you're creating a library it can be a big problem.
Admin
Yep, and it's you that creates the objects, so presumably you're the one making the decision, no?
So, in fact, what you're saying is "Ruby does stuff if I tell it to", no?
You may be confusing Ruby the language with Rails the framework, which does indeed do things behind your back. But, you know, those things that rails does are pretty well documented (well, mostly, anyway). Ruby the language does an awful lot less "behind the scenes magick" than, for example, C++.
Now, to address your "critical size" thing, I think, respectfully, you're tied to the strongly typed language shackles, and moving to a dynamically typed language is a fairly major step. I got lucky in that I learned Smalltalk before C++[1]; I'm used to dynamic languages. There are very big differences in the way things get done, and you have to think about things differently. The point is, it's extremely rare to need to know the actual datatype of some random object.
If you create it, you know what type it is. If you're sensible, you give it a name that expresses what it represents, for example (using some RoR here but it's relatively easy to understand)
new_person = User.new({:name => "Simon"})
Easy. It's a User. I've just created it, I've given it a name that explains what it is.
Next up, what comes back from more complex method calls, like getting all the users from the database
users = User.find(:all)
Now, I don't need to know what exact type 'users', or its content have; I know it's an enumerable collection of objects implementing the 'User' interface. users[0] may actually be an Administrator, it may be a Client, it may be of any other class, I don't care. All I care about is that it can do all the things that a plain vanilla User can do. Because it's all under my control.
Now there may be cases where I want to know what actual type an object has. In most cases, this actually means "I want to know if this object can do something in particular", which I can find out using something like
some_random_object.respond_to?(:some_selector)
for example
users_with_salaries = users.reject{|user| !user.respond_to?(:salary)}
total_salaries = users.inject(0){|sum, user| sum+user.salary rescue sum}
The use of reject and the corresponding negated comparison is to get around a problem in rails, by the way. It would be better to use find_all, but rails 1.x seems to have broken that. Feh. The latter[2] uses a trick to avoid having to ask if user responds to :salary as that question is already being asked when you do user.salary. What you'll notice is that I'm not getting hung up on what actual type the objects have, only with what they can do.
Not that this means that dynamically typed languages are necessarily better or worse than strongly typed ones. They both have their places, their advantages and disadvantages. I personally feel more at home with the flexibility a dynamically typed language provides, and the fact that I can generally get away with less LOC using them. It's also my opinion that strongly typed languages are a crutch for poor programmers[3] and mostly outdated now that the performance advantages are less important (not to say that, for example, C++ has no place today, it plainly has).
Like I said, I have no feeling on how C# falls into the scheme of things, not using it.
Simon
[1] FWIW, I started programming over 25 years ago, and have been doing C++ since it was generally delivered as a preprocessor in front of a straight C compiler.
[2] The inject method on an enumerable collection takes an accumulator with a starting value (in this case 0), and then passes that and each object in the collection into the block, expecting a value back which replaces the current version of the accumulator. The fragment above starts with 0, then enumerates through each object in the users collection, adding the user's salary to the 'accumulator' value, and returning that value at the end.
[3] That should get some flames rolling in :)
Admin
I disagree
Admin
That'll be Moronic Object Oriented Software Engineering then.
Admin
Last Post!
Admin
Maybe, SaveToDatabase does not save the contact-information to the database, but retrieves it in stead? And LoadFromContact may mean: load the record in the database with the provided information ?
Hmm ... WTF indeed.
Admin
That would confirm it to the original source of this technique - Visual Basic, where the language does not care whether it's a public variable or a property function.
Admin
Nice try. Although I'm not usually one to get in the way of a good anti-VB flame, you're well off course here. Sorry.
The source of the technique is deep in the basics of object orientation. Remember. We have objects. Objects get sent messages. Those messages have selectors indicating what you want the receiving object to do. On receipt of a message with a particular selector, the object does something. Or not, as the case may be.
So, if I have a class that responds to selectors x and x=, or getX and setX, or whatever convention defines for a particular language / framework, there's no guarantee that those will go through accessors or be simple reflection of instance variable accesses. Not only that, as the sender of the message, I shouldn't care. All I care about is the value(s) returned and any possible side effects, which should be understood or documented, as these give the "contract" that the class is designed to.
Now, the implementation of a language might break this somewhat idyllic scheme, and differentiate between direct variable accesses and calls of methods. But that's the fault of the language designer, who has generally done away with the concept of messages and selectors, or at least allowed people bypass message sending and go inside of objects to bugger about with their innards. If you start using direct variable accesses (which break encapsulation anyway) and then find you have to change everything to start using methods, then that's your fault.
Now, if, as it seems from previous comments, C# differentiates between instance variables and "properties" (which I assume are the public reflections of instance variable accessors), I'd consider that a bit of a WTF, to be honest. No more of a WTF than C++ and so on, but hey. And the point remains that one should not (except in a few edge cases) be poking around in the guts of some other object, whether or not the language allows you to do it.
Simon
Admin
Nope. I ask for an object by calling a function. This is NOT the same as "create me an object of a given type". In fact, many parts of Ruby are specifcally designed to isolate you from the type of an object, to the extent that the Pickaxe recommends that you check whether an object responds to a specific function, rather than whether it's of a given type.
In many respects, this is A Good Thing. In many respects, it isn't. Ruby has its place, as I said. But then so do more verbose languages such as C#
In a rare an uncharactieristic instance of verboseness, in this case yes it does. A lot of the time it does make assumptions in order to reduce typing, and sometimes these assumptions are correct. Sometimes they are not, and I have to hunt through my code to find out what the assumption is, where it came from, and how to override it.
Nope, never used the Rails framework.
LOL, maybe. Maybe it is just that I'm used to being able to look through my code and having it tell me what's happening. But I don't think so. I think there is a critical size, though maybe it's just not a size you've reached. It's not particularly a size I've reached, at least not on my own - we are talking tens of thousands of lines of C# code, here. But in my previous job I did some work on a relatively large project written in C#. I worked on some little config apps which would have worked just as well had they been written in Ruby, but the main app would have been a mess.
It's easy since the definition and the reference are close together. It's easy since you're calling the User constructor directly. It's easy because you only have one class that represents a person. As your project grows, these conditions don't apply anymore. Sorry, but your arguments just don't work for very large projects.
In an ideal world, large projects would simply be a collection of smaller projects. But this is the real world, not an ideal one.
Besides, you aren't the only one who needs to know about this type - the program itself often needs to check types, and this is easier in a strongly typed language, since all elements have a definite type.
Sorry, where do you get the idea that you don't care what type of users you're dealing with?
users = User.find(:all)
users.each do |u|
grant(u, "c:/sensitive_location", "full_control")
end
In most cases, yes, but supposing two classes have methods doing different things but called the same thing? In the context of that class, it might make sense, but just asking if it has that method isn't always enough.
That basically reiterates what I was saying. I have nothing against dynamic languages, but I strongly feel that they are not suitable for very large projects, simply because you have to keep more of a track on what's going on, because the compiler or IDE won't do it for you.
A tyrannical compiler can be a good thing, because it forces you to think about what types your objects should be. In my example above, I might have to specifically handle guest users, administrators, normal users and so on. But then while I'm doing this, a light should be going off saying that I'm granting access to some sensitive location - should I really be doing this for guest users? Maybe, but the point is I have to think about it - I SHOULD have to think about it. In a smaller project, I can keep track of this because I'm more likely to remember what a particular method does, what types are stored where. In a larger project, I don't have a chance of that.
Admin
I admit I've mostly managed to avoid C++ up to now, but doesn't it actually require a helluva lot more work than Ruby? I mean, Ruby will do a lot more type conversion behind the scenes, it will manage memory and scope behind the scenes, as will C#... C++ is essentially a procedural language (C) with classes bolted on top - that means I even have to tell it how to create and destroy those classes. In terms of types, it does more than C# (since C# will very rarely automatically convert a type for you) but less than Ruby.