Posts Tagged ‘solid code’
July 5th, 2016
When defining enums set the first of the items to a non-zero value.
This way one knows whether one has forgotten to set the value.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| using System;
public class Program
{
private static int SomeNonInitiatedValueFromSomewhere = 0;
public enum MyEnum
{
AnItem = 1,
AnotherItem
}
public static void Main()
{
var myEnum = MyEnum.AnotherItem;
MyEnum myForgottenEnum = (MyEnum)SomeNonInitiatedValueFromSomewhere;
Console.WriteLine("Now={0}", DateTime.Now.ToString("HH:mm"));
Console.WriteLine("myEnum={0}", myEnum); // This enum is set.
Console.WriteLine("myForgottenEnum={0}", myForgottenEnum); // This enum is not set.
}
} |
from https://dotnetfiddle.net/17tQMB
January 6th, 2010
When you want to populate a dropdown listbox with customers
class Customer{ int Id; string Name; ...}
and have to write
myDropdownListbox.DisplayMember = "Name";myDropdownListbox.DataMember = "Id";
or
myGridColumnCustomerName.DatatMeber = "Name";
you really get a sour taste in your mouth.
Having magic strings like above spread in your code is really bad since it always compiles but might fail runtime. This means more manual tests. Which in turns means a certain friction against renaming properties while refactoring.
I have been in way too many projects where one table has a field ItemNumber when it should have been ItemCount and where some fields are called Nr while another Number and these names are spread up in the layers to reach the presentation layer where they surface as magic strings like the examples above.
Luckily there is a solution in Dotnet 3 with LINQ. It isn’t the prettiest but it fails compile time when it should and that is considered a good thing.
( I won’t bother with explanation – just read the code. )
When you want to populate a dropdown listbox with customers
class Customer{ int Id; string Name; ...}
and have to write
myDropdownListbox.DisplayMember = "Name";myDropdownListbox.DataMember = "Id";
or
myGridColumnCustomerName.DatatMeber = "Name";
you really get a sour taste in your mouth.
Having magic strings like above spread in your code is really bad since it always compiles but might fail runtime. This means more manual tests. Which in turns means a certain friction against renaming properties while refactoring.
I have been in way too many projects where one table has a field ItemNumber when it should have been ItemCount and where some fields are called Nr while another Number and these names are spread up in the layers to reach the presentation layer where they surface as magic strings like the examples above.
Luckily there is a solution in Dotnet 3 with LINQ. It isn’t the prettiest but it fails compile time when it should and that is considered a good thing.
( I won’t bother with explanation – just read the code. )
// The Code.
<
class ReflectionUtility
{
public static string GetPropertyName<T, TReturn>(Expression<Func<T, TReturn>> expression)
{
MemberExpression body = (MemberExpression)expression.Body;
return body.Member.Name;
}
public static string GetMethodName<T, TReturn>(Expression<Func<T, TReturn>> expression)
{
var body = expression.Body as UnaryExpression;
var operand = body.Operand as MethodCallExpression;
var argument = operand.Arguments[2] as ConstantExpression;
var methodInfo = argument.Value as System.Reflection.MethodInfo;
return methodInfo.Name;
}
}
class MyClass
{
public int MyField;
public int MyPublicProperty { get; set; }
public string MyReadonlyProperty { get { return string.Empty; } }
public int MyMethod() { return 0; }
private MyClass() { } // To make sure the class doesn't need a default constructor.
}
class Program
{
static void Main(string[] args)
{
string fieldName = ReflectionUtility.GetPropertyName((MyClass x) => x.MyField);
Console.WriteLine(string.Format("MyClass.MyField:{0}", fieldName));
Debug.Assert("MyField" == fieldName);
string propertyName = ReflectionUtility.GetPropertyName((MyClass x) => x.MyPublicProperty);
Console.WriteLine(string.Format("MyClass.MyPublicProperty:{0}", propertyName));
Debug.Assert("MyPublicProperty" == propertyName);
propertyName = ReflectionUtility.GetPropertyName((MyClass x) => x.MyReadonlyProperty);
Console.WriteLine(string.Format("MyClass.MyReadonlyProperty :{0}", propertyName));
Debug.Assert("MyReadonlyProperty" == propertyName);
string methodName = ReflectionUtility.GetMethodName<MyClass, Func<int>>((MyClass x) => x.MyMethod);
Console.Write(string.Format("MyClass.MyMethod:{0}", methodName));
Debug.Assert("MyMethod" == methodName);
Console.Write(Environment.NewLine + "Press any key.");
Console.ReadKey();
}
< }
Honor those who should. (This link contains a comment regarding generic methods that I’d like to impolement in CompulsoryCat.)
Update: When copy-pasting through manoli.net some angle brackets got dropped. This is, hopefully, fixed now. Otherwise – get the source here: http://selfelected.pastebin.com/f77563a02
Update:
Check out Compulsorycat. It is my F/OSS library with some of these functions.
Honor those who should. (This link contains a comment regarding generic methods that I’d like to impolement in CompulsoryCat.)
Update: When copy-pasting through manoli.net some angle brackets got dropped. This is, hopefully, fixed now. Otherwise – get the source here: http://selfelected.pastebin.com/f77563a02
Update:
Check out Compulsorycat. It is my F/OSS library with some of these functions.
September 15th, 2008
Correction; Considered a warning.
Here is a good rule-of-thumb: If you have to write an SQL with Select Distinct, do adjust your chair, get a cup of coffee, walk around the office but above all talk to someone else because Select Distinct is a symptom of something being wrong, either in the database or in your solution.
/* Select Distinct is normally not needed when your database is lagom normalized. But if you do need a Select Distinct then this is a very good example of a situation that needs to be documented.*/
July 3rd, 2008
There is something called defensive programming http://en.wikipedia.org/wiki/Defensive_programming that is supposedly something good. I believe so too but it might have a way of hiding bugs.
In defensive programming you recieve data and inspect it for flaws. When it is possible you manipulate the data so it is correct and usable again. This is good so as much your code works.
But when you are in a project where your code is just a cog in a bigger machinery this approach is not necessarily the best; by recieving and hiding flawed data a bug somewhere else is hidden.
In the example in Wikipedia a string limited to 1000 characters is manipulated. The suggested solution is to truncate the string and keep rowing as if there wasn’t a leak in the first place. Depending on the circumstances the bug might be at the caller and by removing the very bug instead of the symptoms the very problem disappears.
According to Fail at once an error should surface as soon and close to the source as possible. The chances for data resulting of the bug to propagate, is then smaller and the bug tracking is probably faster.
In the example it would have been better to throw an exception than to just keep on with data, now faulty in another way than to start with.
Or like this: if a user writes an essay of 2000 characters he probably wants to know that it cannot be saved the very moment ctrl-S is pressed instead of 2 days later when proof reading, when the last 1000 characters are gone both from mind and binary space. Or an operator of a tube bending machine prefers to know if his machine is faulty when he is working at it instead of two weeks later when the tubes are buried inside a wall somewhere.
About 4 years after I wrote the above I found that at least one more has the same opinion (pdf); someone way more known than I.
June 29th, 2008
I have written 2 articles tagged as Fail at once without explaining what the filosophy behind the name is. Shame on me.
It is an old truth that the earlier a bug is found the cheaper it is to fix.
Automated tests tests things that can go wrong; but what if those things couldn’t even go wrong in the first place?
Code that won’t compile won’t make it into production. Ever.
It is cheapest to not write any errors at all.
Today Fail at once does two things: It stops compiling when it notices something is wrong and at all other times it tries to help the programmer do the right thing.
Typical example of the first is to always use type safe variables and the latter to name things in such a way that there is one very natural way to write the code. By using this explicitly and intelligently you get a leverage for writing better code faster.
June 18th, 2008
The default constructor
public Customer()
{
}
is seldom needed while working with business objects. Honestly – how do you need an object that is not fully populated? Do you have a Customer or do you not? A few situations comes to mind where an almost-Customer is needed but they all smell of refactoring, i.e. base class, sub class and two constructors.
To make sure I don’t have an object that is not fully populated I make sure the default constructor is not reachable. Either through creating other constructors or by making it private the times it is needed internally. Instead I create a constructor that takes all necessary parameters to fully populate itself. If there are variants I create more constructors. I am not afraid of writing code but I strongly dislike putting bugs into production. Hence Fail At Once.
Sometimes it is handy to have a “Set” method taking all parameters and calling it from the constructor but this is just a variant of the pattern above that objects that are not correctly populated are very seldom useful.
If you don’t like writing “normal” constructors them make them static and call them Create or something obvious.
Another advantage with this routine is when adding (or removing) mandatory fields. Then there is one and only one place to update to make the compiler show you all places to update.
I have noticed that it is hard to make lists in the GUI without having a default constructor but this, I presume, is just the exception that confirms the rule.
Bugs that can’t compile will not go into production.
November 8th, 2007
This message will be repeated in english further down.
Hur får man rättningar och funktionalitet så fort som möjligt genom dörren?
Hur får man så få buggar som möjligt i produktion?
Jag fick en gång kommentaren från en vän “Men du levererar väl aldrig otestad kod?”. Det var en komplimang och en kommentar till att jag just då satt i ett projekt som skulle leverera den högsta kvaliteten jag levererat hittills, dessutom rakt ut i fabrik
Mitt svar förvånade honom “Jag testar inte.” Jag lät honom hämta andan. “Rättning: jag testar så lite som möjligt och mycket kod går rakt ut i produktion otestad.”
Sedan följde en förklaring. En förklaring jag har dragit för alla i projektet:
“Använd kompilatorn för att fånga fel.”
Vanligtvis när man talar om system med hög kvalitet pratar man om testning. Massor med manuella tester med speciella konsulter man hyr in som är specialiserade på test. Dyrt. Men det blir dyrt med hög kvalitet.
Bullshit.
Manuella tester är dyrt och tar lång tid.
Modernare utveckling innehåller enhetstester.
Jag förespråkar Fail At Once för att slippa många enhetstester och manuella dito.
Det är viktigt att fånga fel så fort som möjligt. De allra bästa är att inte skriva dem alls.
Där är jag inte ännu.
How do you ship patches and functionality as fast as possible?
How do you get as few bugs as possible in production?
I once got a comment from a friend “But you never deliver untested code?” It was meant as a compliment and comment to my job then; I was working in a project that was delivering the highest quality I have ever delivered; right onto factory floor.
My answer surprised him “I don’t test.” I let him catch his breath. “Correction: I test as little as possible and as much code as possible goes into production untested.”
I had to explain, the same explanation everyone in the project had heard.
“Use the compiler to catch errors.”
Normally when one talks about high quality system one also mentions testing. Lots of manual tests with consultants specialised on testing. Expensive. But high quality is expensive.
Bullshit.
Manual tests are expensive and take lots of time.
The more modern unit testing is cheaper.
I recommend Fail At Once to get rid of many unit tests and manual ditto.
It is important to catch errors as fast as possible. The best is to not write them at all.
I am not there yet.
September 13th, 2007
There is a nifty operator in dotnet2, ??
Use it to get the first thing that is not null.
string name = firstName ?? lastName ?? email ?? “Has no name”;
sets name to the first value that is not null.
To set a string to empty if it is null but keep it otherwise:
message = message ?? string.Empty;
which is the same as
if( null == message ){
message = string.Empty;
}
One might consider it harder to read but I think it is a matter of getting used to.
Beware though of its low precedence.
string user = userName ?? string.Empty + description;
will always return only the userName if there is one. Alas, insert a pair of parenthesises:
string user = ( userName ?? string.Empty ) + description;
On the side I prefer
string.Empty
to
“”
because with string.Empty I am totally sure the string is empty. There is no chance what so ever that a stray space slipped in between the quotes.
September 11th, 2007
It is very easy to inherit from your controls in dotnet/VS.Net. Just add a class and let it inherit from any Control. That’s it!
To use it either reload the project (possibly the IDE) and drag it from the toolbox to the left. This is only possible in VSNet2005 I think. Or do as I, open the myclass.designer.cs file and edit the declaration in the bottom. Recompile and edit the compiling error at the instantiation. That’s it!
VSNet2005 does not interfere with your hacking of the .designer.cs file. Unless you are building for WinCE that is.
Why inherit then?
There is really no need to do it all the time.
But keep it in your head so the moment you need some common functionality in your form you can put it in BaseForm.
Update:
Always inherit from the grid control. There is a very good reason regarding type safety and differentiation of data and view for this. I hope to write about this in a not to far future.
Update:
Hacking designer.cs in VSNet2008 for WindowsMobile(6.1) works alright but you will probably get an “InvalidCastException” and a pointer to something like
((System.ComponentModel.ISupportInitialize)(this._myControl)).BeginInit();
The error is explained here and the solution is to just comment/delete the rows
((System.ComponentModel.ISupportInitialize)(this._myControl)).BeginInit();
and
((System.ComponentModel.ISupportInitialize)(this._myControl)).EndInit();
September 10th, 2007
Before you start fixing a bug. Make sure you can recreate it.
Before changing the first line of code always reproduce the bug.
Without having the same indata and getting the bug and the same indata and not getting the bug you can never be sure it is fixed.