Are there any guidelines or general consensus towards the size of a 'Get' in terms of lines of code? I have a Get method on a member that has quite easily grown to 30 lines of code here. I'm not sure at what point this should be pulled out into a method. But then I'd only be calling it something like GetMyString and assigning the value to another member and calling it in the constructor anyway.
Is it ever worth doing this?
Is this too subjective for SO?
dcastro's answer is good but could use some expansion:
it doesn't take long to return
That's not quantified; let's quantify that. A property should not take more than, say, ten times longer than it would take to fetch a field.
it doesn't connect to external resources (databases, services, etc)
Those are slow and so typically fall under the first rule, but there is a second aspect to this: failure should be rare or impossible. Property getters should not throw exceptions.
it doesn't have any side effects
I would clarify that to observable side effects. Property getters often have the side effect that they compute the property once and cache it for later, but that's not an observable side effect.
Not only is it bad philosophically for getting a property to have an observable side effect, it can also mess up your debugging experience. Remember, when you look at an object in the debugger by default the debugger calls its property getters automatically and displays the results. If doing so is slow then that slows down debugging. If doing so can fail then your debugging experience gets full of failure messages. And if doing so has a side effect then debugging your program changes how the program works, which might make it very hard to find the bug. You can of course turn automatic property evaluation off, but it is better to design good properties in the first place.
It's not really the size that matters (no pun intended).
It's ok to have your logic in a getter as long as
it doesn't take long to return
it doesn't connect to external resources (databases, services, etc)
it doesn't have any side effects
These are only some of the guidelines for proper property usage.
Edit
The above guidelines share one ideal: Property accessors should behave like data access, because that's what users expect.
From the book Effective C# by Bill Wagner:
Properties are methods that can be viewed from the calling code like
data. That puts some expectations into your users’ heads. They will
see a property access as though it was a data access. After all,
that’s what it looks like. Your property accessors should live up to
those expectations. Get accessors should not have observable side
effects. Set accessors do modify the state, and users should be able
to see those changes.
Property accessors also have performance
expectations for your users. A property access looks like a data field
access. It should not have performance characteristics that are
significantly different than a simple data access.
Property accessors
should not perform lengthy computations, or make cross-application
calls (such as perform database queries), or do other lengthy
operations that would be inconsistent with your users’ expectations
for a property accessor.
Bonus by Alberto: http://msdn.microsoft.com/en-us/library/vstudio/ms229054%28v=vs.100%29.aspx
It's not necessarily bad, but if it were me it would make me nervous and I'd be looking to try and break it up somehow. A getter is a method so simply pulling the whole thing into a 30+ line method would be a waste of time in my opinion. I'd be trying to chop it up. E.g. if it was a loop with some checks, extracting the checks as methods or some such.
This is a common bad practice to shove a whole bunch of lines into a Get method.
I have something installed in visual studio called CodeMaid. It has something called a CodeMaid Spade which rates each method and gives you a score. The higher the score the worse your method is. It can be used on properties too. I suggest you give it a try, it helps with formatting, indentation and a bunch of other good practices as well
As a general guideline, a method should not have more lines than fit on one screen. If you have to scroll, it's too large. Split it into smaller methods.
I am implementing a web service that receives information and needs to map them on the MS Dynamics CRM.
So, when it comes to setting OptionSet values, since I am not the one who implemented the CRM, I have no idea what indices are set up. All I know are the labels. Naturally so do the ones consuming my service. e.g. I call an Opportunity Warm or Cold, not 10033004 and 10033005. But I still need to set this value on the Opportunity entity.
I have found this link - but I think it's really overkill and if that's the only way I can access the OptionSet, then that's just sad.
Couple of options here.
Use the metadata services e.g. Your link, I agree this feels like a bit of an overkill, but you could add caching to reduce the overhead of multiple service calls. If you really don't know what the value is going to be at run time then this is probably the best way.
Just hard code it, if you know at compile time what the values will be then this is probably the quickest option. I've done this before and its usually fine. However this will obviously break if someone changes CRM.
Use the strongly typed classes, this is effectively hard coding just the system does it for you. However you will have regenerate them if CRM changes.
So none of these are a perfect option I'm afraid, but they all get the job done.
Edit
Re: option 3; I mean the early bound entities described here: http://msdn.microsoft.com/en-us/library/gg328210.aspx. I'm not sure how much they will help in this situation. They are strongly types classes which are used instead of the entity class. E.g. contact.firstname instead of entity["firstname"]. I suppose you might be able to use them as a form of metadata - never tried it myself though. Also it has the same problem as option 2, when CRM changes they need to be updated and then compiled.
In this case I'm veering towards option 1 and querying the metadata services, if you do this once and cache the results at the beginning of your process you will always have the most up to date information. This example shows how to get all the metadata in the system http://msdn.microsoft.com/en-us/library/jj603008.
I have this solution (that works), but i would like to know if theres a way to make a loop that checks if the method-name is posted, and if it is -> run the method. Current code:
if (HttpContext.Current.Request["FunctionName"] != null)
{
switch (HttpContext.Current.Request["FunctionName"])
{
case "DoStuff":
DoStuff();
//... etc
Hope you get the idea, otherwise ill elaborate.
Thanks in advance!
You could call GetType().GetMethod(HttpContext.Current.Request["FunctionName"], new Type[]{}) which would return a MethodInfo that you could invoke. I wouldn't though for a few reasons:
The general diciness of do-whatever-the-user-tells-you is high enough that even with the assurance that this was done in a class where every method (including inherited) was safe to run, I'd rather be more active in parsing requests from potentially malicious users.
There'd have to be lot of such methods before the convenience of this outweighed the relative cost, and at that point I'd wonder about the specification of the resource in question. URIs should map to a resource with well defined meanings, rather than including everything but the kitchen sink. There should only be a small number of possible values for the function name anyway.
The title says you're taking this from the query string, which suggests you're reacting to a GET by doing different things. GETs should be "look at" operations, that return the state of the thing looked at. This can certainly involve doing quite a bit (classic example is a search that does a lot of complicated comparisons, possibly against a variety of different sources, but is still a "look at" operation). The query string should not select a choice of actions, that should be done by examining the information POSTed to the resource - or better yet POSTed to the resources with completely different URIs for each sort of operation.
based on the follow up comments I would create context specific handlers rather than one handler to process all generic requests. otherwise integrate a MVC framework into the webforms project and let the MVC framework handle object/method delegation.
When working with service oriented applications we often use system types to identify / query our business entities.
IList<Product> GetProductsByUserAndCategoryId(int userId, int categoryId);
However we can't prevent developpers to pass another identifier which is not a "User Identifier" and not a "Category Identifier", or maybe inverse the ids on method call.
So a solution is to use Strongly Type Identifiers, like this :
IList<Product> GetProductsByUserAndCategoryId(UserId userId, CategoryId categoryId);
GetProductsByUserAndCategoryId(new UserId(123), new CategoryId(456));
What do you think about this ? Pros and cons ?
Pros and cons ?
Well, first off, this only shifts the moment of validation; it still has to happen, preferably as soon as a UserId (…) is instantiated. You also have to see whether this really has any benefits in your system at all.
On the other hand, I do think that it prevents bugs by disambiguating between inherently ambiguous numbers. Letting the same type int stand for two completely unrelated things can actually be dangerous.
In a recent code review (for a course at University) the no. 1 error students had made was to use an integer in the wrong way. Having used different types as in your example would effectively have prevented this source of errors altogether.
So, in summary, I don’t think there’s a blanked answer but I am generally in favour of such idioms. This is one of the real benefits of a strict type system.
The only real con for me is having to type extra code. You code becomes more tightly defined, which is a good thing, but now there is extra friction to actually getting it written. It is just a matter of will spending the extra time and effort up front pay off in saved maintenance and dependability later.
It is the same with any methodology. The TDD guys spend time building scaffolding and tests up front with the hope it will make there code more reliable and more easily maintainable. -- Many of them say it saves time upfront as well...but I have my doubts :) --
Ultimately I agree with Mr. Rudolph. This is the strength of strict type systems; Use it to your advantage.
Is it bad practice to have a string like
"name=Gina;postion= HouseMatriarch;id=1234" to hold state data in an application.I know that I could just as well have a struct , class or hashtable to hold this info.
Is it acceptable practice to hold delimited key/value pairs in a database field– just for use in where the data type is not known at design time.
Thanks...I am just trying to insure that I maintain good design practices
Yes, holding your data in a string like "name=Gina;postion= HouseMatriarch;id=1234" is very bad practice. This data structure should be stored in structs or objects, because it is hard to access, validate and process the data in a string. It will take you much more time to write the code to parse your string to get at your data than just using the language structures of C#.
I would also advise against storing key/value pairs in database fields if the other option is just adding columns for those fields. If you don't know the type of your data at design time, you are probably not doing the design right. How will you be able to build an application when you don't know what data types your fields will have to hold? Or perhaps you should elaborate on the context of the application to make the intent clearer. It is not all black and white :-)
Well, if your application only passes this data between other systems, I don't see any problems in treating it as a string. However, if you need to use the data, I would definitely introduce the necessary types to handle that.
I think you will find your application easier to maintain if you make a struct or class to hold the data and then add a custom property to return (and set) the string you been using. This method will take the fields and format it in the string that you are already using and do the reverse (take the string and fill the fields) This way you maintain maximum compatibility with your old algorithms.
Well one immediate problem with that approach is embedded escape chars. Given your example what would happen if the user entered their name as follows:
Pet;er
or
Pe=;ter
or
pe;Name=Yeoi;
I am not sure what state data it is you are trying to hold, and without any context it's hard to make valid suggestions. Perhaps a first step would be to replace this with a key value pair, at least that negates the problem mentioned above and means you don't have to parse strings regularly.
I try to not keep data in any string based formats. But I encountered several situations, in which it was not possible to know in advance how the structure of the data will be (e.g. it was possible for the customer/end-user to dynamically add fields).
In contrast to your approach, we decided to store the data in XML, e.g. in your case this would be something similar like this:
<user id="1234">
<name>Gina</name>
<postion>HouseMatriarch</position>
</user>
This gives you the following advantages:
The classes to work with the data (read/write) are already available in the framework (e.g. XmlDocument or XML serialization)
you can easily exchange the data with other systems (if/when required)
You can store the data in a file
you can store the data in a database column (xml data type). You can even query that column when using SQL Server (although I'd try to avoid storing data in XML, that has to be queried)
using XML allows to add additional fields to your data at any time
Update: I'm not sure why my answer was downvoted that much - maybe it is because of the bad example. Therefore I'd like to make it clear: I would not use XML for properties such as an ID/primary key of a user, or for standard properties like "name", "email", etc. But for "extended/dynamic" properties (as described above) I still think this is an easy and elegant solution.
If you want to store structured data in a string I think you should use a standard notation such as JSON.
It's bad practice because of the amount of effort you have to go to, to construct the strings and parse them later. There are other more robust ways of serialising data for passing between systems.
For core business data, suitably designed classes will be far simpler to maintain, and with all the properties strongly typed, you'll know early on when you mis-type a property name.
As for key-value pairs, I'd say they're sometimes Ok, sometimes not. If there are a lot of possible values, but not a lot of actually owned values, then it can be perfectly all right to use KVPs. Sebastian Dietz's alternative of having a separate column for each field would result in a lot of empty fields in that case. It would also mean extra work altering the table every time you needed a new one.
None of the answers has mentioned normalization yet, so I thought I would. When database fields are involved, one of the key principles of normalization is that each field in a table only represents one thing. Delimited fields violate that principle.
One of the guys at Red Gate Software posted this article along those lines that you may find useful.
Well it just means that it is less searchable or indexable as a hashtable would be. It would also require a bit of processing to get into a state where it could be easily used by other bits of code. For example a bit of code that queries the id in that data would be something horrible such as:
if(dataStringThing.Substring(26, 4) == SomeIdInStringFormat)
So yes in most cases it is bad practice. However in other cases where this might be a default format that you need to retain the data in or performance means that you only should parse it as and when required. So it may not be a bad thing.
I would suggest myself if you have reasons to keep it in that format that it might be best to transform it into a class that separates the fields but also create a ToString() implementation on that class that restores it to the original format if you also need this. If the performance of it is a concern then modify this object to only parse the source into the fields in the class the first time those fields are accessed.
To re-iterate nothing in isolation is necessarily a bad practise. Bad practises are context dependant.
It (hopefully) obviously shouldn't be a normal choice. But there are cases where it's useful or necessary.
I can't think of any cases that wouldn't involve it being part of a communications protocol with some external service (e.g. a database connection string), so you're probably stuck with the format.
If you have a choice in the format (perhaps you are writing both sides of a system which can only communicate using strings), then at least choose something structured and well known. Examples of such have been given elsewhere, but the prime ones are naturally going to be XML or JSON. CSV, or some other delimited format may be useful in very simple cases (such as the database connection string) - but pay special attention to escaping delimiter characters (as the "Bobby Tables" joke (already referenced in another comment) nicely illustrated - google for him if you are not familiar with that one).
Your mention of a database suggests that this may be where the focus is. Are you trying to serialise application objects? (there are other ways of doing that). As another poster said, this may be a sign of a design that needs rethinking. But if you do need to store unknown datatypes in a DB, then XML may be an appropriate choice - especially if your DB supports XML fields. It's a bit of a minefield, though, so make sure you are familiar with how they work first.
I think it is not that bad when you are using a StringList for manging your string.
Especially when the structure of a e.g configuration-string (or configuration-database field) must be flexibel.
But in normally you should not do this, because of this disadvantages.
It all depends on what you're trying to accomplish.
If you need a heirarcical format of data or lots of fields that preserve data type, then no... a parsed string is a bad idea.
However, if you just need to transmit a string across a service and byte-conservation is important, then a Tag-Data pair may be exactly what you need.
If you do use a parsed string, it's important to be able to get at the data inside and quickly manage it. If you want an example TDP class, I posted one today to my website:
http://www.jerryandcheryl.net/jspot/2009/01/tag-data-pairs.html
I hope that helps.
I suggest considering these usage factors.
If you are processing the data within your own code, then you can use whatever data structures you wish. However, you may have issues developing your own implementation of a complex data structure, so consider using a pre-built one instead. Many come with whatever programming platform you may be using, while many more are documented in various books, articles, and discussions both printed and online. If you properly isolate your work from others, then you can safely do whatever you want.
On the other hand, if you need to share that data with others, then most careful consideration should be given. If you must share the data with an API, or via a storage mechanism (database, file, etc.), or via some transport (sockets, HTTP, etc.), then you should be thinking of others first and foremost. If you wish success and respect from your efforts, then you need to pay attention to standards and conventions and cost. Thankfully, practically any such use that you can imagine has been done before, so you can leverage others' efforts.
In a database, consider how others (and yourself) will be inserting, updating, deleting, and selecting the data. For example, using XML in a database makes all these steps unnecessarily hard and expensive compared to the alternatives. Pay attention to database normalization--learn it if you are not familiar already.
If you are dealing with text, pay attention to character encodings and make them explicit.
If there is an existing standard or convention for what you are doing, honor it. If there is a compelling reason to deviate, then accept the burden of justifying it, explaining it, and making it easy for others to accommodate your choices.
If you control both sides of a communication/transport medium, feel free to optimize. If you don't, err on the side of interoperability. Remember that a primary difference between the two scenarios is the level of self-description embedded with the data: interoperability has lots, optimization drops it based on shared assumptions. Text-rich data is more understandable, but binary is faster.
Think about your audience.