Tuesday, 26 February 2013

Overview of type suffixes


I'd like to bring your attention to an area of the C# specification which is misunderstood by many:

Type Suffixes


Type suffixes are individual characters that you can append to 'any code representation of a value' (called a literal in .NET) which allows you to specify it's exact type.  They only relate to numbers - of which can be defined as one of two forms:

- Integer literals (Whole numbers)
- Real literals (More precision)

If you type 10 into your source code, the compiler will automatically interpret that as an integer type, however if you were to type 10.1 this would be automatically interpreted as a real type (because of the decimal point - the full rules are in the C# specification).  To demonstrate this I'll use the var keyword, which assumes a type based on it's initial assignment:


however if I type 10.1 I get a double (the default for a real literal):



Type suffixes allow you to override these defaults.

For example what if I wanted to specify a float?  Well it turns out there's a type suffix for this, f (single is a synonym for float):

and similarly decimal has m:


The point here is that the literal's type is defined the moment you enter it into the source code and not by the variable you are assigning it to. This becomes important in the scenario when you want to define a type where there isn't an implicit conversion available between the default type, and the variable being defined:


Here you're essentially attempting to store a number inside a box that's too small (usually referred to as a narrowing conversion).  To get around this you need to tell the compiler you actually wanted a decimal:


I understand this topic is somewhat basic, but I believe deserved an overview nonetheless.

Sunday, 14 October 2012

Using tnsnames.ora with your .NET application


Anyone attempting to get their application communicating with an Oracle database will have had to deal with the crucial tnsnames.ora and the information it contains.  And I'll also bet anyone doing this will have seen this beautifully helpful message:

ORA-12154: TNS:could not resolve the connect identifier specified


The reason for this message is that your application cannot find the information it needs to connect to the database, which is usually contained within the tnsnames.ora file (which could be in a number of locations).  The process is analogous to a DNS lookup which resolves a domain name into an IP address, but instead you are resolving an alias into database addresses.

However even if your tnsname.ora contains the correct information, you may still get this error if the application cannot locate the file containing the appropriate identifier.  Of course there are tools such as Tnsping, but I've found its help to be rather limited.

However what isn't very well known is that..

Your .NET application will use the tnsnames.ora file located in the same folder as the executable


As far as I know this isn't documented anywhere and I only discovered it by reading this answer.

The upshot of this means you can ship the file right along side your application, and actively modify it for granular control of your application's database connections.

Hope this helps you out too...

Sunday, 30 September 2012

What I've learnt about professional software development


I've been professionally developing software for four years now and thought I'd reflect on what I've learnt over that time. I've gone for the traditional bullet-point style (hope you don't mind), and they're in no particular order.

Loyalty to your employer is good as long as it isn't blind


The software industry moves fast, but the systems at your current place of employment aren't as likely so. As soon as you feel like you've stopped learning in your current job, it would be wise to get looking for a new one. Too often people stick to a job for too long, only to realise their skill set has become irrelevant (VB6 anyone?). Therefore it is always wise to try your best to be in employment with skills that are currently in demand.

Know it's impossible to know everything, so concentrate on learning what's important (whilst knowing what exists)


Because the software industry is so large and constantly changing it's simply impossible to know everything. However it's equally important to not reinvent the wheel. So you should keep reading blogs, contribute to stackoverflow and go to as many user groups as you can. It's totally ok not to know everything about new technologies, just concentrate on what they can bring to your projects because good developers can learn on the job.

Get a fresh pair of eyes on your problem as soon as you've tried everything


As soon as you find yourself stuck with a particular problem ask one of your peers to take a look.  Don't worry about appearing stupid, your employer would much rather you be productive as soon as possible.  Too many times I've wasted time debugging a problem, only for a colleague to instantly know the solution. Also others have experienced what you haven't, so make use of it. When offered advice take it and ask questions.

Teach and be taught


Sit with your colleagues, write a blog, build up a stackoverflow reputation, but most importantly do anything which gets your thoughts peer reviewed. The only way you learn is by knowing you already don't know everything, or having a long held belief proved wrong wrong.

Absolutely everything should be as simple as possible


Your brain can only hold a handful of concepts at once, around about seven in fact. It therefore make sense that absolutely everything you do should be broken down into the most simple form possible. Read code complete, constantly refactor your code, and use source control to store the the reasons for your changes.

Users don't always know what they want


This is a big one. Users cannot always conceptually visualise what they want, and only get a narrowing of their requirements when they see something tangible. This is where methodologies such as Agile come into play, their iterative processes promote keeping the users in the loop, who can then crystallise their requirements before you've done too much work.

Ask prospective employers lots of questions (and) understand you can't trust recruiters to do this for you


When looking for new employment you should be interviewing the company as much as they're interviewing you. This means lots of questions. Use your experience to avoid previous employment pitfalls, ask them about the state of their source code and what they expect of you.  In fact you should have lots of questions that you've been collecting over your career.

As for recruiters, my experience is that many are only focussed on their commission and will do whatever they can in order to achieve it.  However there are also really good recruiters out there who genuinely keep your interests at heart.  When you cross paths with such a rare breed you should keep in contact with them even if not looking for employment, because you never quite know when you might need them.  I personally use linkedin to keep in contact, and have recommended the best.

Your experience


That's the end of my list, and hopefully I'll have a handful more points over the next four years.  Perhaps you think I've missed some big ones? Use the comments to share your experience, and perhaps I'll learn from you too.

Tuesday, 11 September 2012

Entity Framework and the InvalidOperationException

While recently developing against the Entity Framework I stumbled across the following InvalidOperationException:

The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.

I was trying to insert a new record into a table that contained an auto-generated value. Due to the way the entity model wizard generates it's factory methods meant I had to provide a 'dummy' value for the auto-generated key.

For example in the following code the first parameter is required, even though the database will auto-generate this:

Employee newEmployee = Employee.CreateEmployee(0, "Jansen", "Jan");
context.AddObject("Employees", newEmployee);
context.SaveChanges();

It turns out however that you also need to manually update the model (.edmx) so that it doesn't use the 'dummy' value as the object's key within the ObjectStateManager.

To do this you'll need to open it as text (in solution explorer right click the model, select "Open With" and select "Text Editor").  Then navigate to the auto-generated property in the storage part of your model (within the <edmx:storagemodels> tag) and add StoreGeneratedPattern="Identity" as an attribute.

For example change
<Property Name="ID" Type="number" Nullable="false" Precision="11"/>
to
<Property Name="ID" Type="number" Nullable="false" Precision="11" StoreGeneratedPattern="Identity"/>

The StoreGeneratedPattern is an enumeration which indicates whether the column in the database needs a value on insert and update operations, and since it's auto-generated on the database it doesn't.  Therefore by specifying this on the attribute you prevent the exception being thrown.

Bear in mind however this manual modification needs done every time after adding tables or refreshing from the database.  For more information see the changes made to an .edmx file by the update model wizard.

Thursday, 6 September 2012

Stuck debugging? Leave it!

I'd like to share an experience I've recently had:


This has happened many many times to me since becoming a developer, and I've begun to understand that if I find myself against a brick wall I should leave it and come back to it later.

It isn't just me who seems to have come to this conclusion, in fact many developers are actually attempting to take advantage of it when planning projects.  In the psychological world this phenomenon is termed: The incubation effect

I believe this has a very apparent effect in the field of software development, and I'd say most have experienced this at least once, especially as our job is to solve problems not just code.  In fact there was recently a discussion over on Stack Exchange where most answers cite 'taking a break' as one of the best ways to get over programmers block.

The science behind this isn't concrete, however it does suggest the activity we do should be unrelated, and sleep is even better as it helps process the information of the day and solve problems. Which corroborates with my experience.

So next time you're staring at your screen blankly, littered with breakpoints, and you're no where near a solution you should give up and come back later with a fresh mind and a fresh perspective. What do you think?

Thursday, 30 August 2012

LINQ or readability?

We all know that cyclomatic complexity is directly correlated to bugs in your code and a great way to remedy this is by reducing the lines of code you write.

I recently stumbled across this article by Scott Hansleman which considered a number of scenarios where LINQ has the ability to improve our collective code-bases, through reducing lines.

To take an extract from his blog:
I visit a lot of customers and look at a lot of code. I also worked with a number of large production code bases in my previous jobs and I see a lot of ifs, fors and switches. I see loops inside of loops with ifs inside them, all doing various transformations of data from one form to another....I'd much rather write these one line operations than the loop and if above...(which are) simpler, terser, and less error prone than loops of loops.
However, like Scott points out, it is equally important to emphasise you should not cloud the water in an attempt to condense lines.  Readability is also king.

Here is an example that ReSharper recently suggested be condensed.

Code with a foreach loop:
decimal? total = 0;

foreach (var halfHour in halfHours)
{

    total += Calculate(data, halfHour.DateAndTime.Date, new
 List<string> {halfHour.HalfHourNumber});

}

return total;

Code using LINQ:
return halfHours.Aggregate<HalfHour, decimal?>(0, (current, halfHour) => 
current + Calculate(data, halfHour.DateAndTime.Date, new 
List<string> {halfHour.HalfHourNumber}));

This is certainly one for judgement, but I'd go with the most readable any day. So what do you think?


Update:

I've become aware that infact this article is relating to a lambda expression rather than LINQ itself (which can't be used interchangeably), and therefore the post isn't factually correct in that regard. I'll be describing in a future post what each of these mean and the differences between the two, as I hadn't been aware of the distinct difference myself. The core point of the post remains however.

Wednesday, 22 August 2012

The importance of code

Recently I've noticed that when people learn of my occupation 9 out of 10 times the first question out of their mouth is "so what languages can you write?" which is a question that troubles me somewhat.

The problem is the assumption that software development is simply a set of distinct languages that can be learned and mastered in the same way you would learn Spanish or French.  In reality the multitude of languages that exist are merely tools and nothing more, and the field of software development has (very) little to do with knowing languages.

A great example are the hoards of developers who would call themselves a C# developer but wouldn't touch VB with a bargepole.  Well here's a secret, the differences are purely syntactical, they use the same paradigm (object oriented) and the both compile to the same intermediate language so in reality they already "know" VB.

The real question we should be asking each other are "what technologies are you working on, and does it challenge any of my currently accepted norms?"

We must be really careful not to pigeon-hole ourselves into language-shaped boxes, but to understand that the languages we use at work are just the tip of the iceberg. Software development is a craft in the same way as other professions.

I'll leave you with this fitting analogy:
Code to a developer is the same as a pencil is to an engineer.