I was reading this post where Jeff Atwood complained about too many shiny tools that only waste our time and of which there are so many that the whole shining thing becomes old.
Of course, I went to all the links for tools in the post that I could find, and then some. I will probably finish reading it after I try them all :)
Here are my refinements on the lists that I've accessed, specific with .NET programming in mind and free tools:
Nregex.com - nice site that tests your regular expressions online and let's you explore the results. Unfortunately it has no profiling or at least a display of how long it took to match your text
Highlight - a tool to format and colorize source code for any flavour of operating system and output file format.
There are a lot more, but I am lazy and I don't find the use for many of them, but you might. Here is Scott Hanselman's list of developer tools from which I am quite amazed he excluded ReSharper, my favourite Visual Studio addon.
Warning: this is going to be one long and messy article. I will also update it from time to time, since it contains work in progress.
Update: I've managed to uncover something new called lookbehinds! They try to match text that is behind the regular expression runner cursor. Using lookbehinds, one might construct a regular expression that would only match a certain maximum length, fixing the problem with huge mismatch times in some situations like CSV parsing a big file that has no commas inside.
Update 2: It wouldn't really work, since look-behinds check a match AFTER it was matched, so it doesn't optimize anything. It would have been great to have support for more regular expressions ran in parallel on the same string.
What started me up was a colleague of mine, complaining about the ever changing format of import files. She isn't the only one complaining, mind you, since it happened to me at least on one project before. Basically, what you have is a simple text file, either comma separated, semicolon separated, fixed width, etc, and you want to map that to a table. But after you make this beautiful little method to take care of that, the client sends a slightly modified file in an email attachment, with an accompanying angry message like: "The import is not working anymore!".
Well, I have been fumbling with the finer aspects of regular expressions for about two weeks. This seemed like the perfect application of Regex: just save the regular expression in a configuration string then change it as the mood and IQ of the client wildly fluctuates. What I needed was:
a general format for parsing the data
a way to mark the different matched groups with meaningful identifiers
performance and resource economy
The format is clear: regular expression language. The .NET flavour allows me to mark any matched group with a string. The performance should be as good as the time spent on the theory and practice of regular expressions (about 50 years).
There you have it. But I noticed a few problems. First of all, if the file is big (as client data usually is) translating the entire content in a string and parsing it afterwards would take gigantic amounts of memory and processing power. Regular expressions don't work with streams, at least not in .Net. What I needed is a Regex.Match(Stream stream, string pattern) method.
Without too much explanation (except the in code comments) here is a class that does that. I made it today in a few hours, tested it, it works. I'll detail my findings after the code box (which you will have to click to expand).
One issue I had with it was that I kept translating a StringBuilder to a string. I know it is somewhat optimized, but the content of the StringBuilder was constantly changing. A Regex class that would work at least on a StringBuilder would have been a boost. A second problem was that if the input file was not even close to my Regex pattern, the matching would take forever, as the algorithm would add more and more bytes to the string and tried to match it.
And of course, there was my blunt and inelegant approach to regular expression writing. What does one do whan in Regex hell? Read Steve Levithan's blog, of course! It was then when I decided to write this post and also document my regular expression findings.
So, let's summarize a bit, then add a bunch of links.
the .NET regular expression flavour supports marking a group with a name like this
(?<nameOfGroup>someRegexPattern)
it also supports non capturing grouping:
(?:pattern)
This will not appear as a Group in any match although you can apply quantifiers to it
also supported are atomic or greedy grouping.
(?>".+")
The pattern above will match "abc" but not "abc"d because ".+ matches the whole pattern and the ending quote is not matched. Normally, it would backtrack, but atomic groups do not backtrack once they failed, saving time, but possibly skipping matches
one can also use lazy quantifiers:ab+? will match ab in the string abbbbbb
posessive quantifiers are not supported, but they can be substituted with atomic groups:
ab*+ in some regex flavours is (?>ab*) in .NET
let's not forget the
(?#this is a comment)
notation to add comments to a regular expression
Look-behinds! - great new discovery of mine that can match an already matched expression. I am not sure how it would hinder speed, though. Quick example: I want to match "This is a string", but not "This is a longer string, that I don't want to match, since it is ridiculously long and it would make my regex run really slow when I really need only a short string" :), both as separate lines in a text file.
([^\r\n]+)(?:$|[\r\n])(?<=(?:^|[\r\n]).{1,21})
This expression matches all strings that do not contain line breaks, then looks behind to check if there is a string begin or a line break character at at most 21 characters behind, effectively reducing the maximum length of the matched string to 20. Unfortunately, this would slow even more the search, since it would only back check a match AFTER the match completed.
What does that mean? Well, first of all, an increase in performance: using non capuring grouping will save memory, using atomic quantifiers will speed up processing. Then there is the "Unrolling the loop" trick, using atomic grouping to optimize repeated alternation like (that|this)*. Group names and comments ease the reading and reuse of regular expressions.
Now for the conclusion: using the optimizations described above (and in the following links) one can write a regular expression that can be changed, understood and used in order to break the input file into matches, each one having named groups. A csv file and a fixed length record file would be treated exactly the same. Let's say using something like (?<ZipCode>\w*),(?<City>\w*)\r\n or (?<ZipCode>\w{5})(?<City>\w{45})\r\n or use look-behinds to limit the maximum line size. All the program has to do is parse the file and create objects with the ZipCode and City properties (if present), maybe using the new C# 3.0 anonymous types. Also, I have read about the DFA versus NFA types of regular expression implementations. DFAs are a lot faster, but cannot support many features that are supported by NFA implementations. The .Net regex flavour is NFA, but using atomic grouping and other such optimizations bridges the gap between those two.
There is more to come, as I come to understand these things. I will probably keep reading my own post in order to keep my thoughts together, so you should also stay tuned, if interested. Now the links:
There is still work to be done. The optimal StreamRegex would not need StringBuilders and strings, but would work directly on the stream. There are a lot of properties that I didn't expose from the standard Regex and Match objects. The GroupCollection and Group objects that my class exposes are normal Regex objects, some of their properties do not make sense (like index). Normally, I would have inherited from Regex and Match, but Match doesn't have a public constructor, even if it is not sealed. Although, I've read somewhere that one should use composition over inheritance whenever possible. Also, there are some rules to be implemented in my grand importing scheme, like some things should not be null, or in a range of values or in some relation to other values in the same record and so on. But that is beyond the scope of this article.
Any opinions or suggestions would really be apreciated, even if they are not positive. As a friend of mine said, every kick in the butt is a step forward or a new and interesting anal experience.
Update:
I've taken the Reflected sources of System.Text.RegularExpressions in the System.dll file and made my own library to play with. I might still get somewhere, but the concepts in that code are way beyond my ability to comprehend in the two hours that I allowed myself for this project.
What I've gathered so far:
the Regex class is no sealed
Regex calls on a RegexRunner class, which is also public and abstract
RegexRunner asks you to implement the FindFirstChar, Go and InitTrackCount methods, while all the other methods it has are protected but not virtual. In the MSDN documentation on it, this text seals the fate of the class This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.
The RegexRunner class that the Regex class calls on is the RegexInterpreter class, which is a lot of extra code and, of course, is internal sealed
.
The conclusion I draw from these points and the random experiments I did on the code itself are that there is no convenient way of inheriting from Regex or any other class in the System.Text.RegularExpressions namespace. It would be easy, once the code is freely distributed with comments and everything, to change it in order to allow for custom Go or ForwardCharNext methods that would read from a stream when reaching the end of the buffered string or cause a mismatch once the runmatch exceeds a certain maximum length. Actually, this last point is the reason why regular expressions cannot be used so freely as my original post idea suggested, since trying to parse a completely different file than the one intended would result in huge time consumption.
Strike that! I've compiled a regular expression into an assembly (in case you don't know what that is, check out this link) and then used Reflector on it! Here is how to make your own regular expression object:
Step 1: inherit from Regex and set some base protected values. One that is essential is base.factory = new YourOwnFactory();
Step 2: create said YourOwnFactory by inheriting from RegexRunnerFactory, override the CreateInstance() method and return a YourOwnRunner object. Like this:
class YourOwnFactory : RegexRunnerFactory { protected override RegexRunner CreateInstance() { return new YourOwnRunner(); } }
Step 3: create said YourOwnRunner by inheriting from abstract class RegexRunner. You must now implement FindFirstChar, Go and InitTrackCount.
. You may recognize here a Factory design pattern! However, consider that the Microsoft normal implementation (the internal sealed RegexInterpreter) has like 36Kb/1100 lines of highly optimised code. This abstract class is available to poor mortals for the single reason that they needed to implement regular expressions compiled into separate assemblies.
I will end this article with my X-mas wish list for regular expressions:
An option to match in parallel two or more regular expressions on the same string. This would allow me to check for a really complicated expression and in the same time validate it (for length, format, or whatever)
Stream support. This hack in the above code works, but does not real tap in the power of regular expressions. The support should be included in the engine itself
Extensibility support. Maybe this would have been a lot more easy if there was some support for adding custom expressions, maybe hidden in .NET (?#comment) syntax.
I've stumbled upon a link toward SQL 2000 best practices analyzer. Aparently, it is a program that scans my SQL server and tells me what I did wrong. It worked, somewhat, because at some tests it failed with a software exception, but then I searched the Microsoft site for other best practices analyzers and I found a whole bunch of them!
The last link is for a framework that loads all analyzers so you can run them all. It's a pretty basic tool, there is still work to be done on it, but you can also make your own analyzers and the source code for the program and the included ASP.Net plugin is also available.
Acquires, purchases, whatever... they paid for it and they will have it. Sun will have MySql. Does that mean that they want to go towards easily usable SQL servers or that they want to compete with Oracle? PostgreSQL would have been a more appropriate choice in that case. Will MySql for Java be like SQL server is for .NET ? Anyway, 1 billion dollars is selling short, I think. Youtube was two. Is a media distribution software more important than a database server?
Small quote: MySQL's open source database is the "M" in LAMP - the software platform comprised of Linux, Apache, MySQL and PHP/Perl often viewed as the foundation of the Internet. Sun is committed to enhancing and optimizing the LAMP stack on GNU/Linux and Microsoft Windows along with OpenSolaris and MAC OS X. The database from MySQL, OpenSolaris and GlassFish, together with Sun's Java platform and NetBeans communities, will create a powerful Web application platform across a wide range of customers shifting their applications to the Web.
I am going to quickly describe what happened in the briefing, then link to the site where all the presentation materials can be found (if I ever find it :))
The whole thing was supposed to happen at the Grand RIN hotel, but apparently the people there changed their minds suddenly leaving the briefing without a set location. In the end the brief took place at the Marriott Hotel and the MSDN people were nice enough to phone me and let me know of the change.
The conference lasted for 9 hours, with coffee and lunch breaks, and also half an hour for signing in and another 30 minutes for introduction bullshit. You know the drill if you ever went to one of such events: you sit in a chair waiting for the event to start while you are SPAMMED with video presentations of Microsoft products, then some guy comes in saying hello, presenting the people that will do the talking, then each of the people that do the talking present themselves, maybe even thank the presenter at the beginning... like a circular reference! Luckily I brought my trusted ear plugs and PDA, loaded with sci-fi and tech files.
The actual talk began at 10:00, with Petru Jucovschi presenting as well as holding the first talk, about Linq and C# 3.0. He has recently taken over from Zoltan Herczeg and he has not yet gained the necessary confidence to keep crouds interested. Luckily, the information and code were reasonably well structured and, even if I've heard them before, held me watching the whole thing.
Linq highlights:
is new in .NET 3.0+ and it takes advantage of a lot of the other newly introduced features like anonymous types and methods, lambda expressions, expression trees, extension methods, object initializers and many others.
it works over any object defined as IQueryable<T> or IEnumerable (although this last thing is a bit of a compromise).
simplifies our way of working with queries, bring them closer to the .NET programming languages and from the just-in-time errors into the domain of compiler errors.
"out of the box" it comes with support for T-Sql, Xml, Objects and Datasets, but providers can be built (easily) for anything imaginable.
the linq queries are actually execution trees that are only run when GetEnumerator is called. This is called "deffered execution" and it means more queries can be linked and optimised before the data is actually required.
in case you want the data for caching purposes, there are ToList and ToArray methods available
Then there were two back-to-back sessions from my favourite speaker, Ciprian Jichici, about Linq over SQL and Linq over Entities. He was slightly tired and in a hurry to catch the plain for his native lands of Timisoara, VB, but he held it through, even if he had to talk for 2.5 hours straight. He went through the manual motions of creating mappings between Linq to SQL objects and actualy database data; it wouldn't compile, but the principles were throughly explained and I have all the respect for the fact that he didn't just drag and drop everything and not explain what happened in the background.
Linq to SQL highlights:
Linq to SQL does not replace SQL and SQL programming
Linq to SQL supports only T-SQL 2005 and 2008 for now, but Linq providers from the other DB manufacturers are sure to come.
Linq queries are being translated, wherever possible, to the SQL server and executed there.
queries support filtering, grouping, ordering, and C# functions. One of the query was done with StartsWith. I don't know if that translated into SQL2005 CLR code or into a LIKE and I don't know exactly what happends with custom methods
using simple decoration, mapping between SQL tables and C# objects can be done very easily
Visual Studio has GUI tools to accomplish the mapping for you
Linq to SQL can make good use of automatic properties and object initialisers and collection initialisers
an interesting feature is the ability to tell Linq which of the "child" objects to load with a parent object. You can read a Person object and load all its phone numbers and email addresses, but not the purchases made in that name
Linq to Entities highlights:
it does not ship with the .NET framework, but separately, probably a release version will be unveiled in the second half of this year
it uses three XML files to map source to destination: conceptual, mapping and database. The conceptual file will hold a schema of local object, the database file will hold a schema of source objects and the mapping will describe their relationship.
One of my questions was if I can use Linq to Entities to make a data adapter from an already existing data layer to another, using it to redesign data layer architecture. The answer was yes. I find this very interesting indeed.
of course, GUI tools will help you do that with drag and drop operations and so on and so on
the three level mapping allows you to create objects from more linked tables, making the internal workings of the database engine and even some of its structure irrelevant
I do not know if you can create an object from two different sources, like SQL and an XML file
for the moment Linq to SQL and Linq to Entities are built by different teams and they may have different approaches to similar problems
Then it was lunch time. For a classy (read expensive like crap) hotel, the service was really badly organised. The food was there, but you had to stay in long queues qith a plate in your hand to get some food, then quickly hunt for empty tables, the type you stand in front of to eat. The food was good though, although not exceptional.
Aurelian Popa was the third speaker, talking about Silverlight. Now, it may be something personal, but he brought in my mind the image of Tom Cruise, arrogant, hyperactive, a bit petty. I was half expecting him to say "show me the money!" all the time. He insisted on telling us about the great mathematician Comway who, by a silly mistake, created Conway's Life Game. If he could only spell his name right, tsk, tsk, tsk.
Anyway, technically this presentation was the most interesting to me, since it showed concepts I was not familiar with. Apparently Silverlight 1.0 is Javascript based, but Silverlight 2.0, which will be released by the half of this year, I guess, uses .NET! You can finally program the web with C#. The speed and code protection advantages are great. Silverlight 2.0 maintains the ability to manipulate Html DOM objects and let Javascript manipulate its elements.
Silverlight 2.0 highlights:
Silverlight 2.0 comes with its own .NET compact version, independent on .NET versions on the system or even on operating system
it is designed with compatibility in mind, cross-browser and cross-platform. One will be able to use it in Safari on Linux
the programming can be both declarative (using XAML) and object oriented (programatic access with C# or VB)
I asked if it was possible to manipulate the html DOM of the page and, being written in .NET, work significantly faster than the same operations in pure Javascript. The answer was yes, but since Silverlight is designed to be cross-browser, I doubt it is the whole answer. I wouldn't put it past Microsoft to make some performance optimizations for IE, though.
Silverlight 2.0 has extra abilities: CLR, DLR (for Ruby and other dynamic languages), suport for RSS, SOAP, WCF, WPF, Generics, Ajax, all the buzzwords are there, including DRM (ugh!)
The fourth presentation was just a bore, not worth mentioning. What I thought would enlighten me with new and exciting WCF features was something long, featureless (the technical details as well as the presenter) and lingering on the description would only make me look vengeful and cruel. One must maintain apparences, after all.
WCF highlights: google for them. WCF replaces Web Services, Remoting, Microsoft Message Queue, DCOM and can communicate with any one of them.
If you don't want to read the whole thing and just go to the solution, click here.
I reached a stage in an ASP.Net project where a I needed to make some pages work faster. I used dotTrace to profile the speed of each form and I optimized the C# and SQL code as much as I could. Some pages still were very slow.
Now, I had the idea to look for Javascript profilers. Good idea, bad offer. You either end up with a makeshift implementation that hurts more than it helps, or with something commercial that you don't even like. FireFox has a few free options like FireBug or Venkman, but I didn't even like them and then the pages I was talking about were performing badly in Internet Explorer, not FireFox.
That got me thinking of the time when Firefox managed to quickly select all the items in a <select> element, while on Internet Explorer it scrolled to each item when selecting it, slowing the process tremendously. I then solved that issue by setting the select style.display to none, selecting all the items, then restoring the display. It worked instantly.
Most ASP.Net applications have a MasterPage now. Even most other types of sites employ a template for all the pages in a web application, with the changing page content set in a div or some other container. My solution is simple and easy to apply to the entire project:
Step 1. Set the style.display for the page content container to "none". Step 2. Add a function to the window.onload event to restore the style.display.
Now what will happen is that the content will be displayed in the hidden div, all javascript functions that create, move, change elements in the content will work really fast, as Internet Explorer will not refresh the visual content in the middle of the execution, then show the hidden div.
A more elegant solution would have been to disable the visual refresh of the element while the changes are taking place, then enable it again, but I don't think one can do that in Javascript.
This fix can be applied to pages in FireFox as well, although I don't know if it speeds anything significantly. The overall effect will be like the one in Internet Explorer table display. You will see the page appear suddenly, rather than see each row appear while the table is loaded. This might be nice or not nice, depending on personal taste.
Another cool idea would be to hide the div and replace it with a "Page loading" div or image. That would look even cooler.
Here is the code for the restoration of display. In my own project I just set the div to style="display:none", although it might be more elegant to also hide it using Javascript for the off chance that someone might view the site in lynx or has Javascript disabled.
function addEvent(elm, evType, fn, useCapture) // addEvent and removeEvent // cross-browser event handling for IE5+, NS6 and Mozilla // By Scott Andrew { if (elm.addEventListener){ elm.addEventListener(evType, fn, useCapture); return true; } else if (elm.attachEvent){ var r = elm.attachEvent("on"+evType, fn); return r; } else { alert("Handler could not be removed"); } }
function initMasterPage() { document.getElementById('contenuti').style.display=''; }
Update: this problem appeared for older versions of AjaxControlToolKit. Here is a link that says they fixed this issue since 21st of September 2007.
You are building this cool page using a TabContainer or some other AjaxControlToolKit control and everything looks smashing and you decide to add the UpdatePanels so that everything would run super-duper-fast. And suddenly the beautiful page looks like crap! Everything works, but your controls don't seem to load the cascading style sheet. What is happening is that you make a control visible using update panels and so the CSS doesn't get loaded. I don't know exactly why, you would have to look into the AjaxControlToolKit source code and find out for yourself.
I found two fixes for this. The first is the nobrainer: add another TabContainer or AjaxControlToolKit control in the page, outside any updatepanels, make it visible, but set its style.display to 'none' or put it in a div or span with style="display:none". The second is the AjaxControlToolKit way. In the Page_Load event of the page or user control that contains the TabContainer or AjaxControlToolKit control add this line:
Ok, so I used a javascript script in my page by referencing the external file and it worked. I did the exact same thing with another file and it wasn't loading! After scratching my head bald I've decided to switch the places of the two tags and voila! the script that worked would not load! The one that did not work previously was purring nicely.
After scratching my skull a little more (blood was dripping already) I realized that the script tags are atomic tags, they should have no ending tag. Why would they, the content is specified in the src attribute. But on the DOM page for the script element there is an obscure line saying: Start tag: required, End tag: required. I switched to <script></script> format and it worked.
Oh, you are wondering why the first script worked? Because somehow an atomic script tag is erroneous, but it doesn't return any error. Instead it is treated like a mistyped start tag and the atomic portion of it is ignored. The second script would not load since the browser expected a script end tag. Maybe he even interpreted the second tag as an end tag for all I know.
Apparently, the innerText property of Javascript elements is not available for FireFox or other browsers other than Internet Explorer. FireFox exposes something similar, but with the name textContent. Why would any one of these two butt-heads learn from the other and cooperate for the common good?
The functionality of this property is to expose the inner content of an element minus any html tags. With something like <div><span class="red">Red text<span></div> the div innerText/textContent property returns "Red text". It could also work when setting, stripping tags from the content before setting innerHTML, although it seems that for both implementations setting innerText or textContent is equivalent with setting innerHTML.
There are also links about javascript functions that would replace, improve or otherwise ease the developer's work by adding the same functionality.
I have started with a book recommended by many sites about software architecture and design as a must read: Smalltalk Best Practice Patterns by Kent Beck. It is well written and I can see why it attracted a lot of people, even if there aren't so many Smalltalk programmers out there: it is written for use! That means that the book has less than 200 pages, but each of the specific patterns there are laden with references to others in the book, some even in the next chapters. That's because the book itself is structured to be kept nearby and consulted whenever a new project is started or in progress, not something that you read and forget in a bookshelf, gathering dust.
However, the patterns presented are sometimes useless for a C# programmer, some being already integrated in language and some being not applicable. The fact that Smalltalk works with Messages further complicates things. I did eventually open a link to #-Smalltalk, but who will ever have time for it?
I have decided that rather than reading this book and forgetting or not getting many of the things inside, it would be more efficient searching for a similar book that is more C# oriented.
So, bottom line: great approach, both literary and technical, but a little hard to use for one such as me. Anyone know of a C# Best Practice Patterns book?
My next attempt was in the wonderful world of management! Yes, I was approached by their people, apparently they want me to join them and rule the galaxy. Maybe if they wrote more concise books!!
The Knowledge Management Toolkit: Practical Techniques for Building a Knowledge Management System starts interestingly enough, describing the need of every company to build a way to retain knowledge against employee turnover or plain forgetfulness. Basically what I am doing with this blog. But it goes further than that, quantifying the return on investment for such a KM system, describing ways of rewarding people and encouraging them to use it (it is not something done automatically).
All great, but then it kept going on telling me how the book is going to change my world, rock my boat, help me in my business... after reading the preface, the introduction, the "how it's structured", the marketing bullshit, the first chapter (full of promises about the next chapters) I was completely bored! If there is any technical description of what to do, when to do it, how to do it, why , etc, I didn't find a trace of it in the first chapter. Reading on my PDA from a badly scanned txt file didn't help either.
Besides, I got more and more frustrated. I barely have the time to scratch all I planned on doing in this holiday (while getting nagged on by the wife, the cat and whatever friends I got left) and improving the company workings is not my responsibility. I am the god damn coder! I write code! I have a management system all of my own and I get my ROI by googling a frustrating bug and discovering I solved it a month ago myself and wrote about it here.
So there! If you have a business it is good to have a repository of actual knowledge (a.k.a. processed information) and encourage people to use it so that they don't take all their experience with them when they leave your sorry cheap ass company! I've summarised the entire book for you! I am not reading it anymore. It hurts my sensitive techie soul!
This book started great. It outlaid a structured view of how a software company should function, from the way one designs projects, to code and documentation standards. I really hoped this was the mother load: a book that would show me how a "standard" IT company functions on every level. It wasn't. Mark Horner started it well and ended it badly. A shorter book and more to the point would have been enough.
Bottom line, the book starts in an interesting way, describing what I would call "IT gap analysis", in other words the application of a simple idea: begin with a detailed (and documented) picture of what the current (start) situation is, then describe just as much detail the situation you want to reach (end). From then on, the job of describing the transition becomes orders of magnitude easier. That applies to software projects (start with what the client has and needs, then create the plan to bridge the gap), documentation (start with the functional and end with the structural) and ultimately code (start with abstract classes and interfaces, then fill in the missing code).
Other than that there are some (hopefully) nice references, then a lot of empty space filled up with irrelevant things: description of design patterns (which are nice, but there are books for something like this), a glossary of terms (some were never even used in the book!) and then the general way of describing something, then adding the "Standard acknowledges" part that basically says the same thing as his own description. It generally felt as a student paper from one that needed only a passing grade.
Sorry Mark, better luck next time. I will add here a short summary of what yours truly thought was noteworthy in the book:
use gap analysis for all the levels of your software work. When you define what you have and what you need, filling the blanks becomes easier.
use functional documentation, design documentation and structural documentation to detail what you wanted the software to do, how you designed to solve the problems and what are the basic building blocks of the project (classes, patterns, etc).
use code standards and peer reviews and even external code auditing to improve the quality of code. Refactoring is a must. Popular code development methodologies include Extreme Programming and Rational Unified Process.
the enterprise vs. domain dichotomy. Should a software be started from scratch and done for the current set of requests only, or should it be designed as a general component ready for reuse? I would really go towards the enterprise, even when the profit from the extra work is not immediately obvious. Sometimes things that you have prepared in advance and nobody acknowledged become a real time (and life) saver when unreasonable requests tumble down upon you.
also linked to the enterprise/domain issue: an application framework solution. Create a basic Visual Studio solution that contains common components used in many projects and use it as a startup solution.
use the Visual Studio formatting options to keep your code well formatted. Use a standard of naming variables, methods, properties. My own choice is using lowerCamelCase for inner variables, prefixing the name with an underscore for fields. UpperCamelCase (or Pascal) for methods, properties and class names. Hungarian notation for controls (lbName for a label with a name). I don't really care if one names the control txtName, tbName or tboxName, as long as the prefix is revealing.
use the Obsolete attribute for methods and properties that are intended to be removed in the near future. In my own library I have used methods that became obsolete with the coming of .NET 2.0 and used this attribute to point not only to the obsolescence, but also to the blog entry detailing the reasoning behind it.
this is basically derived from other sources, but I do think it is relevant: best practices recommends using composition over inheritance, wherever possible. I admit that the coding of composition is much more complex, but with the refactoring tools found in Visual Studio and its add-ons (like my beloved Resharper), it becomes similar in complexity.
I was asked to fix a bug and I soon found out that the "bug" was actually IE's regex split implementation! You see? When you split by a string, the resulting array does not contain any empty spaces found!
Ex: 'a,,b'.split(/,/) = ['a','b'] in IE and ['a','','b'] in FireFox.
Searching the web I found this very nice page from regular expression guru Steven Levithan: JavaScript split Inconsistencies & Bugs: Fixed!. You can also find there a link to a page that tests the issues with your browser's Javascript regex.
Bottom line! Use Steven's code to regex split in Javascript.
Most programmers use the ViewState to preserve data across postbacks and the Session to preserve data for a user. There are cases when you want to preserve data across users. Maybe you are using an IHttpHandler and you want to send information through a key between your application and the handler. Or maybe you want to keep data that is resource consuming to acquire, but used by more users of the same application. Here is where Cache comes along.
There are two things you need to pay attention to when you are using the Cache:
While using the syntax Cache[key] is very simple and consistent with the ViewState, Session or other dictionaries you are used to, you need to be aware that in case of the server freeing memory, the cache items will be removed based on priority. Try to use Cache.Add or Cache.Insert with CacheItemPriority.NotRemovable when you are sure you don't want this to happen. The Absolute and Sliding expirations will still work.
I've read somewhere that HttpContext.Current.Cache does not work across users. It's like another Session object. Use HttpRuntime.Cache instead. I also looked in the ASP.Net source code and I found out that HttpContext.Cache returns HttpRuntime.Cache, so I don't see how these two properties could behave any differently. HttpRuntime is much easily usable, though, since it works in situations where HttpContext.Current is null
I was building my nice little web app, you know: grids, buttons, ajax, stuff like that. And of course I had to create CSS classes for my controls, for example a button has the class of butt and the Send button has a class of buttsend. I agree it was not one of the most inspired CSS class name, but look what ajax made out of it:
Nullable types are new to .NET 2.0 and at first glance they seem great. The idea that you can now wrap any type into a generic one that also allows for null values seems valuable enough, especially for database interactions and the dreaded SQL null.
However, having an object that can be both instantiated and null can cause a lot of issues. First of all, boxing! You can define a Nullable<int>, set it to null, then access one of its properties (HasValue). So suddenly a piece of code like obj=null; obj.Property=...; makes sense. But if you want to send it as a parameter for a method, one that receives an object and then does stuff with it, the object must represent the null value, which means it is no longer an instance of anything. Therefore you can't get the type of the variable that was passed to the method!
Quick code snippet: int? i=null; DbWrapper.Save("id",i); With Save defined as: public void Save(string name,object value)
Now, I want to know what kind of nullable type was sent to the method. I can't see that if the parameter signature is object, so I am creating another signature for the method: public void Save(string name,Nullable value)
At this time I get an error: static types cannot be used as parameters. And of course I can't, because Nullable is a generic static type that needs the type of the wrapped value. So the type is actually Nullable<int>. My only solution now is to create a signature for every value type: integers, floating point values, booleans, chars and IntPtrs. String and Object are value types, but they accept null, so Nullable<string> is not used on them, but if you count all the other value types , there are 14 of them!
There is another option that I just thought of: a custom object that implicitly converts from a nullable. Then the method would use this object type as a parameter. I tested it and it works. Here is the code for the object:
Update: There are issues regarding this object, mainly refering to constants. If you pass a constant value like the number 6 a method that expects either Object or NullableWrapper, will choose NullableWrapper. More than that, it will choose a NullableWrapper<byte> since the value is under 256. Adding signatures for int, double, etc causes Ambiguos reference errors. So my only solution so far is to consider the UnderlyingType of even Nullable<byte> as Int32. It is obviously a hack, but I haven't found a good programming solution to it, yet. If you have an idea, please let me know! Thanks.