tag:blogger.com,1999:blog-45859599958526898232024-03-14T01:17:21.348+05:30EllogicalMe. Minus the logic.Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.comBlogger30125tag:blogger.com,1999:blog-4585959995852689823.post-34511033603533403022013-02-09T19:47:00.001+05:302013-02-09T19:47:19.518+05:30NDepend review… Coming up<p>Patrick Smacchia, the lead developer at NDepend, recently offered me an NDepend Professional license and asked for a review.</p> <p>For years, I’ve heard a ton about NDepend but never got to use it for real. Today I installed NDepend and was hit in the face by a bunch of static analysis features that NDepend provides. It’s a pretty slick piece of software and would definitely require a good amount of digging on my part to actually be able to give a comprehensive review.</p> <p>NDepend is amazingly helpful and first impressions have been really nice. First thing you notice is that it would be a key addition to any continuous integration environment. I look forward to exploring it in more detail.</p> <p>So, until the review is published…. adios!</p> Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-43316699578407341992013-02-09T19:33:00.001+05:302013-02-09T19:34:07.582+05:30“Only what you need son”<p>..and the word “need” right there is marked in a monstrous bold font. </p> <p>We look around today and almost everything is on sale. People and businesses want you to buy. They show you that something is available for half the price, tell you that you can buy something in installments, on *easy* EMIs. They want to buy things that you probably do not need. </p> <p>It’s easy to get swayed into the craziness.</p> <p>I’m only human. I too have my needs and wants. I look at such things and ask myself, “Do I want it or Do I need it?”. Only when the answer comes out as “I need it!”, do I ever think of buying that *thing*, whatever it may be. It’s a nice perspective to have.</p> <p>I take my *wants* as luxuries. I sure can afford some luxuries, but I need to look way ahead into the future and make sure that the decisions that I make today do not, in any way, harm my tomorrow.</p> <p>However, every once in a while you need to satisfy at least one “want” that keeps your morale high and gets you through this unfair life, and hope and pray that it gets better one day at a time.</p> Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-11981558435828193552012-02-06T21:50:00.000+05:302012-02-06T22:07:06.068+05:30NCrunch, The Incredible TDD Tool!<div dir="ltr" style="text-align: left;" trbidi="on">
I've been meaning to evaluate and review some development tools since forever. I think I waited so long just because I never found a tool that grabbed my attention to a level where it could really get me on my butt and make me jot down a review. Well, now we have such an awesomized tool - NCrunch!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihwXzhlXz64ifyXYhlftYl_hqloIqxVPDTNgtjgfk2cFZ2mOpYnQC6GPYUAPj0-AruLLLb9T5mw5wdFXbQirDHGJzoq3fvz5UkXBGWSk3N1ZBzvBl4HETfgFtq_M9dNO5CdylsRwmQbRA/s1600/NCrunch_0.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="88" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihwXzhlXz64ifyXYhlftYl_hqloIqxVPDTNgtjgfk2cFZ2mOpYnQC6GPYUAPj0-AruLLLb9T5mw5wdFXbQirDHGJzoq3fvz5UkXBGWSk3N1ZBzvBl4HETfgFtq_M9dNO5CdylsRwmQbRA/s320/NCrunch_0.PNG" width="320" /></a></div>
<br />
<br />
Calling NCrunch just another TDD tool would be terrible injustice to it's developers.<br />
<br />
<b>NCrunch is -</b><br />
<ul style="text-align: left;">
<li>An automated parallel continuous testing tool for Visual Studio.</li>
<li>A code coverage analyzer</li>
<li>A performance analyzer</li>
<li>And last, but not the least, incredibly smart!</li>
</ul>
<div>
<div>
Think about the usual steps you go through with test driven development:</div>
<div>
<ul style="text-align: left;">
<li>Write test</li>
<li>Build and run tests</li>
<li>Write code</li>
<li>Build and run tests</li>
<li>Refactor code</li>
<li>Build and run tests</li>
</ul>
</div>
<div>
As a highly optimised test runner, NCrunch can knock half of these steps away by automating them completely - so you end up with:</div>
<div>
<ul style="text-align: left;">
<li>Write test</li>
<li>Write code</li>
<li>Refactor code</li>
</ul>
</div>
</div>
Yes! The tests are automatically built and run in the background. Continuous feedback is provided on the fly, thereby making test development easier. As soon as the tests are build-able, NCrunch runs the tests and provides immediate feedback. Writing assertions is a pleasure!<br />
<br />
And there's much more apart from this main feature. But, let's look at how a developer would use NCrunch. Here, we have written a simple test.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFmOC0XNNsXtG5AI9dMyK2kQxy4NwR53-Fu-690QLQP7Q9AfAcujQ5HIz9phkxWRg0E9y9T3k7mKOIoouti4DyPwRN_fplIaYGWWcjAxzNG67q5uxunokc6fncdbdHr9oli2OzKHiHUMs/s1600/NCrunch_1.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgFmOC0XNNsXtG5AI9dMyK2kQxy4NwR53-Fu-690QLQP7Q9AfAcujQ5HIz9phkxWRg0E9y9T3k7mKOIoouti4DyPwRN_fplIaYGWWcjAxzNG67q5uxunokc6fncdbdHr9oli2OzKHiHUMs/s640/NCrunch_1.PNG" width="640" /></a></div>
<br />
The view above shows the normal view that a developer shall have when NCrunch is disabled. Go ahead and enable NCrunch. Go to <b>NCrunch -> Enable NCrunch</b>. And now you see your editor shows something like this. Note that we have defined a default implementation for the Add() method that returns zero.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNzNERetaUt3cA-mWmzue4gJxR-X68a90EcisqO3kYfj1bCBYXW32DJqo-fpkBmeypJ9ZokULrEyP_uQ2WPfIIWncd1zE8LOPjkWJVIIVpxr9xC1duGrfvFW3EZvX-sjLF7YDA0hjhyphenhyphenLM/s1600/NCrunch_2.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="268" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNzNERetaUt3cA-mWmzue4gJxR-X68a90EcisqO3kYfj1bCBYXW32DJqo-fpkBmeypJ9ZokULrEyP_uQ2WPfIIWncd1zE8LOPjkWJVIIVpxr9xC1duGrfvFW3EZvX-sjLF7YDA0hjhyphenhyphenLM/s640/NCrunch_2.PNG" width="640" /></a></div>
<br />
We shall go back and fix the method Add(). Also, you don't even need to save your files for NCrunch to be able to run your tests!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfwd0dKV2pEKW92-YQnMBvTqMx2yt13pjhubd8kKAdew-zH5iye8wvMTUlMksbA_P482bXQHbchJNnWkSxuD0ocRQLaDwqnR-1V-Xt-msiG_cLuUzqNmwetCH_rO68TRV3YO4Aa18HyuE/s1600/NCrunch_3.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="241" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfwd0dKV2pEKW92-YQnMBvTqMx2yt13pjhubd8kKAdew-zH5iye8wvMTUlMksbA_P482bXQHbchJNnWkSxuD0ocRQLaDwqnR-1V-Xt-msiG_cLuUzqNmwetCH_rO68TRV3YO4Aa18HyuE/s400/NCrunch_3.PNG" width="400" /></a></div>
<br />
We now add another test to our suite.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI4mwF8CKt5PKIdXe4lC_WfHtt9KjgYvrno0zDRHwpgt6qMucUNs2L-wW3F8gQXeRC7zmPCmFvVZa-_ChSe-WGMqYxg3RB3UJbLK3ueCRe5Zy12sV8BNVQgw9esru7zzID5SOTeCLJcCE/s1600/NCrunch_4.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="132" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhI4mwF8CKt5PKIdXe4lC_WfHtt9KjgYvrno0zDRHwpgt6qMucUNs2L-wW3F8gQXeRC7zmPCmFvVZa-_ChSe-WGMqYxg3RB3UJbLK3ueCRe5Zy12sV8BNVQgw9esru7zzID5SOTeCLJcCE/s640/NCrunch_4.PNG" width="640" /></a></div>
<br />
While writing the test however, we see an error. This is because the test is wrong! Correct the test! I just love this level of immediate feedback! Hover over the red cross mark and it shows you a tooltip that tells you exactly what went wrong. (Click on image to view)<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOtfRVlh0jIyITYfmf8vvNo0bpksqbcxJaz3UkjLQbN7q5iOmW7NVu7PIDdcVgr-5pmeOhYLqjmuDs8zhwDWdHCBlJ8-4Hf1SGGPijI78Cyry-T6asF3RN6FX4KyhhkVzzv6Gm2-RhirA/s1600/NCrunch_5.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="155" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOtfRVlh0jIyITYfmf8vvNo0bpksqbcxJaz3UkjLQbN7q5iOmW7NVu7PIDdcVgr-5pmeOhYLqjmuDs8zhwDWdHCBlJ8-4Hf1SGGPijI78Cyry-T6asF3RN6FX4KyhhkVzzv6Gm2-RhirA/s640/NCrunch_5.PNG" width="640" /></a></div>
<br />
Fix the failing test and everything shows green again! NCrunch also handles exceptions gracefully and the tooltips indicate which exception occurred and where.<br />
<br />
<b>Code Coverage</b><br />
The lines of code marked green indicate the parts of code that are covered by tests. This makes it very easy to spot areas that have not been covered yet, write covering code or eliminating any dead code. The following tooltip on the test tells you that the test is covered by 1 passing test.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1vWiZoGjqMk7WOzetBmto8gPxb2qx73-vC7Vy8q4FMKM6HFEtJLZPabheLO8akLUShlEgCwBVCmpzCZTQxbLzOrHYWeCXGoLxNt6knACcyS553-uw495wyZI4zCwmFKLhDcF4TShPH9o/s1600/NCrunch_6.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1vWiZoGjqMk7WOzetBmto8gPxb2qx73-vC7Vy8q4FMKM6HFEtJLZPabheLO8akLUShlEgCwBVCmpzCZTQxbLzOrHYWeCXGoLxNt6knACcyS553-uw495wyZI4zCwmFKLhDcF4TShPH9o/s640/NCrunch_6.PNG" width="640" /></a></div>
<b><br /></b><br />
<b>Performance metrics</b><br />
NCrunch also provides information about performance metrics and hot-spots in the tested code, thereby allowing you to identify parts of code that might induce a performance problem in the long run. The previous figure shows you the execution time of the test. The next figure shows you that the method being tested is too slow.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOL6GMwO_saSvm7u8sLRrxwFj5o27-3RUbWvX8Iif5mxEJLM2o0x7WkxXd_bKOUoStr0TP3hDE-DqbAvAHHrWp7jUR5zYkd-6QHb5iP05SltVrU7JZHoqpjokoa41HGt3NcybhgKWSvz4/s1600/NCrunch_7.PNG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="148" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOL6GMwO_saSvm7u8sLRrxwFj5o27-3RUbWvX8Iif5mxEJLM2o0x7WkxXd_bKOUoStr0TP3hDE-DqbAvAHHrWp7jUR5zYkd-6QHb5iP05SltVrU7JZHoqpjokoa41HGt3NcybhgKWSvz4/s640/NCrunch_7.PNG" width="640" /></a></div>
<br />
The yellow marker indicates that the code is executing really slow and that you should take a look to see if that's normal.<br />
<br />
<b>What frameworks does NCrunch support?</b><br />
Supported testing frameworks are:<br />
<ul style="text-align: left;">
<li>NUnit</li>
<li>MS Test</li>
<li>Xunit</li>
<li>MbUnit</li>
<li>MSpec</li>
</ul>
Supported languages and .NET versions are:<br />
<ul style="text-align: left;">
<li>C#</li>
<li>VB.NET</li>
<li>F#</li>
<li>.NET Framework v2.0 and above</li>
<li>Visual Studio 2008</li>
<li>Visual Studio 2010</li>
<li>Visual Studio 11 Developer Preview</li>
</ul>
<b>Pricing?</b><br />
I'm sure that there has been a huge level of effort that has gone into developing this tool. But, the software is free to be used as long as it is in beta. Let's hope that on release the developers will price it economically.<br />
<br />
There's a lot of other stuff that NCrunch supports that would make your life a wee bit easier. Go check out the NCrunch blog for updates! I really hope that this tool becomes a standard in everyday development for most software development firms.<br />
<br />
Have fun with NCrunch!<br />
<br />
<b>Links:</b><br />
NCrunch main website - <a href="http://www.ncrunch.net/">http://www.ncrunch.net/</a><br />
NCrunch Download - <a href="http://www.ncrunch.net/download.htm">http://www.ncrunch.net/download.htm</a><br />
NCrunch on Visual Studio Code Gallery - <a href="http://visualstudiogallery.msdn.microsoft.com/6946579c-c7d9-48ce-b039-994d30b85116">http://visualstudiogallery.msdn.microsoft.com/6946579c-c7d9-48ce-b039-994d30b85116</a><br />
<br /></div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com2tag:blogger.com,1999:blog-4585959995852689823.post-78437126029750656992012-02-04T10:07:00.003+05:302012-02-04T10:11:56.047+05:30IBM Research | Ponder This - IBM's monthly mathematical puzzles<div dir="ltr" style="text-align: left;" trbidi="on">
A few days ago I came across this website by IBM - <a href="http://domino.research.ibm.com/Comm/wwwr_ponder.nsf/pages/index.html" target="_blank">IBM Research | Ponder This</a>. I'm no big fan of solving insane mathematical puzzles that boggle the mind. But, I really liked the level of the complexity these problems have. It has been going on for quite some time.<br />
<br />
I've always wondered what the reason could be for such a huge corporation to run such mathematical puzzles. Maybe they are unable to solve these problems and want help from people. That would be funny. They can easily get other people to solve their problems for practically nothing.<br />
<br />
I'm definitely not able to solve any of these problems yet. But, you might - if you're really know your math. Looks like they just posted a new one for February 2012. All the best!</div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-43557263487524037572012-02-03T18:51:00.002+05:302012-02-06T20:18:32.733+05:30Write to a console window from a Windows application<div dir="ltr" style="text-align: left;" trbidi="on">
Ever wondered how you could write out to a separate console window from your Windows application rather than writing to a log file? You might need to do that for a number of reasons – mostly related to debugging. Here’s how you do it:<br />
<br />
Predefined APIs are available in kernel32.dll that will allow you to write to a console.<br />
<br />
<a href="http://msdn.microsoft.com/en-us/library/ms681944(VS.85).aspx">AllocConsole</a><br />
<br />
<a href="http://msdn.microsoft.com/en-us/library/ms683150(VS.85).aspx">FreeConsole</a><br />
<br />
<a href="http://msdn.microsoft.com/en-us/library/ms681952(VS.85).aspx">AttachConsole</a><br />
<br />
AllocConsole() attaches your process to a console window where the process’ standard output will be redirected. A process can be associated with only one console, so the AllocConsole() function fails if the calling process is already associated with a console. FreeConsole() is used to detach the process from the current console and AttachConsole() can be used to attach associate a console with the current process.<br />
<br />
The following shows a sample usage of the feature.<br />
<pre class="brush: csharp">private void button1_Click(object sender, EventArgs e)
{
new Thread(new ThreadStart(delegate()
{
AllocConsole();
for (uint i = 0; i < 1000000; ++i)
{
Console.WriteLine("Hello " + i);
}
FreeConsole();
})).Start();
}</pre>
<br />
You’ll need to import the AllocConsole and FreeConsole API from kernel32.dll.<br />
<pre class="brush: csharp">[DllImport("kernel32.dll")]
public static extern bool AllocConsole();
[DllImport("kernel32.dll")]
public static extern bool FreeConsole();</pre>
<br />
And you can always make it Conditional if you want to use it only while debugging.<br />
<pre class="brush: csharp">private void button1_Click(object sender, EventArgs e)
{
new Thread(new ThreadStart(delegate()
{
AllocateConsole();
for (uint i = 0; i < 1000000; ++i)
{
Console.WriteLine("Hello " + i);
}
DeallocateConsole();
})).Start();
}
[Conditional("DEBUG")]
private void AllocateConsole()
{
AllocConsole();
}
[Conditional("DEBUG")]
private void DeallocateConsole()
{
FreeConsole();
}
</pre>
</div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-1929931832017277772012-01-30T20:57:00.001+05:302012-02-04T09:50:30.647+05:30VSX Add-in Development Adventures: Window.Object returns NULL<div dir="ltr" style="text-align: left;" trbidi="on">
I’m in the middle of developing an add-in for Visual Studio 2008, a simple one that would help our in-house code review process. If you’ve ever written a VS add-in, you’d know the basic routine – Visual Studio creates the basic class Connect derived from IDTExtensibility2, then you put in your code in the methods OnConnection, OnDisconnection, OnAddInsUpdate, OnStartUpComplete and OnBeginShutdown.<br />
<br />
I developed a few user controls (UserControl objects) for showing some UI as tool windows. One of them was AddCommentView which is just a dumb UserControl that displays some textboxes and buttons and also takes in some input. I deployed this control as a separate DLL and linked it to the add-in. Then, as usual, the following code should do the job of creating the tool window.<br />
<pre class="brush: csharp">if (_addCommentWindow == null)
{
object objTemp = null;
string guid = Guid.NewGuid().ToString();
Window2 toolWins = (Window2) this._applicationObject.Windows;
// Create the tool window view for adding the comment
_addCommentWindow = toolWins.CreateToolWindow2(_addinInstance, "Controls.dll",
"Controls.AddCommentView", "Add Comment", "{" + guid + "}", ref objTemp);
} </pre>
<br />
And like always it worked just fine till I tried to test it and that’s when I realized something wasn’t quite right.<br />
The CreateToolWindow2 method has two outputs – the tool window (which is returned by the method) and the hosted user control (the ref parameter ‘objTemp’ in this case). The hosted user control can also be retrieved through the Window.Object property of the returned tool window. The problem was – no matter what I tried the Window.Object property always returned null and so did ‘objTemp’.<br />
<pre class="brush: csharp">AddCommentView addCommentViewControl = _addCommentWindow.Object as AddCommentView;
addCommentViewControl.StartLine = selection.AnchorPoint.Line;
addCommentViewControl.EndLine = selection.ActivePoint.Line;</pre>
<br />
The solution – I was acting dumb, very dumb. Visual Studio requires all hosted controls to be visible to COM. After adding the attribute to the entire assembly using <b>[assembly: ComVisible(true)]</b> , everything started working like a charm (you can apply it even to the individual control if you don’t want to make the entire assembly COMVisible).<br />
<br /></div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-76572145236626134992012-01-30T20:38:00.001+05:302012-02-04T09:51:55.101+05:30Defining custom Dictionary keys in C#<div dir="ltr" style="text-align: left;" trbidi="on">
Ever so often we come across cases where we need to store objects mapped to other objects in a Dictionary. And in most of these cases, the default solution of using the object reference as a key doesn’t really work. For example, if an object Person { Name = “Foo” } is mapped to value ‘x’, another object Person { Name = “Foo” } does not get us to the value ‘x’, although we probably would expect it to return ‘x’.<br />
<pre class="brush: csharp">class Person
{
public int Age { get; set; }
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
var p1 = new Person() { Age = 30, Name = "p1" };
var p2 = new Person() { Age = 31, Name = "p2" };
var p3 = new Person() { Age = 32, Name = "p3" };
var personVsBonus = new Dictionary<Person, int>();
personVsBonus[p1] = 1000;
personVsBonus[p2] = 2000;
personVsBonus[p3] = 3000;
var personToFind = new Person() { Age = 31, Name = "p2" };
Console.WriteLine(personToFind.Name + " will be given a bonus of " + personVsBonus[personToFind]);
}
} </pre>
<br />
The above program gives throws a KeyNotFoundException as the dictionary was not able to locate the entry searched as it was doing a reference comparison.<br />
In such cases you need to define your own implementation of what the dictionary should consider as the key value. In the example we just discussed, we might like the property Person.Name to be considered as the key. Whenever a dictionary needs to decide where an item should be located, it calls GetHashCode(), whose return value decides where the item shall be stored. If GetHashCode() returns the same value for two different objects, the Equals() method is called with both objects being compared. The result of the Equals() method tells the dictionary whether the objects are the same or different.<br />
<strong><br /></strong><br />
<strong>Solution 1:</strong><br />
Implement the IEquatable interface for the Person class. This means that, “Hey, now the Person object will tell you whether it is the same as another Person object!”. You also need to override the Object.GetHashCode() method and write a good hash generating algorithm that generates unique values (int). Here, I use a simple method that just returns the length of the person’s name.<br />
<pre class="brush: csharp"> class Person : IEquatable<Person>
{
public int Age { get; set; }
public string Name { get; set; }
#region IEquatable<Person> Members
public bool Equals(Person other)
{
return this.Age.Equals(other.Age)
&& this.Name.Equals(other.Name);
}
#endregion
public override int GetHashCode()
{
return this.Name.Length;
}
}</pre>
<br />
Run the program after making these additions and the program works fine. The dictionary is now able to find appropriate values.<br />
<br />
<strong>Solution 2:</strong><br />
There will be times when the key type might be a sealed type or you might not be allowed to change the key object’s properties. The Dictionary type provides us the IEqualityComparer interface that we can implement to provide our custom definitions based on the key object’s properties without having to modify the key’s properties.<br />
<br />
Here is the modified code:<br />
<br />
<pre class="brush: csharp"> class Person
{
public int Age { get; set; }
public string Name { get; set; }
}
class PersonEqualityComparer : IEqualityComparer<Person>
{
#region IEqualityComparer<Person> Members
public bool Equals(Person x, Person y)
{
return x.Age.Equals(y.Age)
&& x.Name.Equals(y.Name);
}
public int GetHashCode(Person obj)
{
return obj.Name.Length;
}
#endregion
}</pre>
<br />
Also remember to use the comparer object while creating the dictionary.<br />
<br />
<pre class="brush: csharp">var personVsBonus = new Dictionary<Person, int>(new PersonEqualityComparer());</pre>
<br />
Run the program after making these changes and the program works just fine!<br />
<br />
The <strong>most important thing to remember </strong>here is that your definition of GetHashCode() shall decide how fast your dictionary can lookup an entry. Be very careful while taking these solutions into consideration as weak hash generation might lead you to long-term scalability issues where the dictionary might take more and more time to lookup entries in large dictionaries.<br />
<br /></div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-33855023220893413412012-01-29T15:31:00.001+05:302012-02-04T09:52:52.873+05:30TaskList in Visual Studio - Making it better<div dir="ltr" style="text-align: left;" trbidi="on">
It was great to come across a new feature in Visual Studio - The TaskList. Well, yes it isn't new but, it certainly was new to me. I had never really come across this wonderful feature until last week when secretGeek blogged that code would suck less if the compiler could raise an error when a // TODO token was detected. A comment from Goran indicated that it was completely possible with the current versions of Visual Studio.<br />
<blockquote class="tr_bq">
A //TODO: token.<br />
Are shown in VS if you click TaskList. Couldn’t live without this one :)</blockquote>
Yeah, sure. Can’t live without it. Although the compiler doesn’t throw you an error, it indicates all parts of code where such tokens appear and hence can be taken care of easily.<br />
<br />
<b>How To Use</b><br />
You can use the TaskList comments for:<br />
<ul style="text-align: left;">
<li>Features to be added</li>
<li>Problems to be corrected</li>
<li>Classes to implement</li>
<li>Place-markers for error handling code</li>
<li>Reminders to check in the file</li>
</ul>
Add your comment in the code preceded by the token. <br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYbFQudMpv-lbdta8wiioxsIyHo22GUhSxTJ6dAKyyDDGaVe2m-94zkhiPRh1xIttuGVgBkVWT9a8Dbx3lzifs2M0Hrd9ilsWcDEnsZ0ezlUdobg-jUoeCnBkrKWMckfiVmjR1Bokqdng/s1600/tasklist_1.bmp" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="85" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYbFQudMpv-lbdta8wiioxsIyHo22GUhSxTJ6dAKyyDDGaVe2m-94zkhiPRh1xIttuGVgBkVWT9a8Dbx3lzifs2M0Hrd9ilsWcDEnsZ0ezlUdobg-jUoeCnBkrKWMckfiVmjR1Bokqdng/s320/tasklist_1.bmp" width="320" /></a></div>
<br />
Once done, open up the TaskList from the View menu.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBzkdmwlGb5lBI9-pRJIB7Lw6ByKv6OEvcSha1UeF3XEciyYUaOqiW9dwiyaKqTUsrRpqWByfdATnytseDv8NMs5cRKtW0lCiFv07MlIFHrBFdhx3nq8-Rjlb-5PMiVR7Gx4bhniBbFq4/s1600/tasklist_2.bmp" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBzkdmwlGb5lBI9-pRJIB7Lw6ByKv6OEvcSha1UeF3XEciyYUaOqiW9dwiyaKqTUsrRpqWByfdATnytseDv8NMs5cRKtW0lCiFv07MlIFHrBFdhx3nq8-Rjlb-5PMiVR7Gx4bhniBbFq4/s640/tasklist_2.bmp" width="290" /></a></div>
<br />
Once the TaskList is up you will see something like this.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqwj7b8GtfzUL1muW1eCklUePnq6Jk14iK85cja2LXvSFGkDpA2cNuVDwZtg7JZQ59pY_vwddQoBV0SSJYOKICn5FWlULKHWnzfaJCd45lXAkaHEvkwZfyzJXPgSQUysyw8YIba77iGQU/s1600/tasklist_3.bmp" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="105" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqwj7b8GtfzUL1muW1eCklUePnq6Jk14iK85cja2LXvSFGkDpA2cNuVDwZtg7JZQ59pY_vwddQoBV0SSJYOKICn5FWlULKHWnzfaJCd45lXAkaHEvkwZfyzJXPgSQUysyw8YIba77iGQU/s400/tasklist_3.bmp" width="400" /></a></div>
<br />
The TaskList also allows custom tokens to be included. Go to Tools –> Options –> Environment –> TaskList.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqbFy8tNQLKdIgUk1hQZgx20igrxd3jeQk3T4572Wd1Q3guBfS3zkU3mYAFoluCijKQAVGG2VuUk7sfg8dLesxjFcTORl-URTc4G918N2BGnwNmbKOCwcwjIgA4TNptojQvjBVrSoNCOw/s1600/tasklist_4.bmp" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqbFy8tNQLKdIgUk1hQZgx20igrxd3jeQk3T4572Wd1Q3guBfS3zkU3mYAFoluCijKQAVGG2VuUk7sfg8dLesxjFcTORl-URTc4G918N2BGnwNmbKOCwcwjIgA4TNptojQvjBVrSoNCOw/s400/tasklist_4.bmp" width="400" /></a></div>
<br />
<b>User Tasks</b><br />
You can add your own tasks in the TaskList by selecting the ‘User Tasks’ selection from the dropdown list on the TaskList toolbox. These tasks aren’t associated with code, but will allow users to add their own high level tasks.<br />
<br />
<b>Extending the TaskList</b><br />
I would like to see the following additional options in the TaskList:<br />
<ul style="text-align: left;">
<li>Task Alarms – which would associate an alarm with a high priority comment to help just in case you forget to take care.</li>
<li>User Tasks to be more specific (by having a file anchor like ‘Comments’) to allow user tasks to be associated with a particular line in code.</li>
</ul>
And no, I’m not waiting on Microsoft to extend it in some other version of Visual Studio. I’m starting right away to write a package that would do this for me, hopefully.<br />
<br />
<b>More Things to Remember</b><br />
With Visual Basic projects, the Task List displays all of the comments in the project. With Visual C# and Visual J# projects, the Task List displays only the comments that are found in the files currently opened for edit. With Visual C++ projects, the Task List displays only the comments that are found in the file currently active in the editor.<br />
<div>
<br /></div>
</div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-20015869717737469372012-01-29T15:14:00.001+05:302012-02-04T09:53:40.673+05:30C# 3.0 for Beginners - Extension Methods - Part 2<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<b>Custom Extension Methods</b><br />
<br />
C# 3.0 enables you with the ability to extend the functionality of existing types. This means that you can write your own extension methods that would give the programmer the feeling that those are just methods provided by the existing type.<br />
<br />
For example, System.Int32 doesn't provide you an IsEven() method which would tell you if the integer is holding an even value. It would obviously be great if you could write a method which does this, just in case you use this functionality heavily in your code. You would then write a method like this<br />
<pre class="brush: csharp">public bool IsEven(Int32 i)
{
if(i%2 == 0)
{
return true;
}
else
{
return false;
}
}</pre>
<br />
Well, that's perfectly fine. But, I wish we could make it more easier. And I bet we can for sure, that's what extension methods are here for. No, we cannot go and implement the IsEven() method for the Int32 type, but C# 3.0 allows you to extend type functionality in a different way.<br />
<br />
Check out the following code. I'm extending the Int32 type to expose the Int32.IsEven() extension method.<br />
<pre class="brush: csharp">public static class MyIntegerExtensionMethod
{
public static bool IsEven(this Int32 i)
{
if (i % 2 == 0)
{
return true;
}
else
{
return false;
}
}
}
public class Program
{
static void Main(string[] args)
{
Int32 n = 9;
Console.WriteLine(n.IsEven());
}
}</pre>
<br />
Let's look at the most important part, the method signature.<br />
<pre class="brush: csharp">public static bool IsEven(this Int32 i)
</pre>
<br />
A template for the above would be<br />
<br />
<b><access_modifier> static <return_type> Method_Name(this <extended_type> <instance_of_type>, <args_list>)</b><br />
<br />
While <access_modifer> and <return_type> are intuitive, special attention is needed at the parameters of the method. The first parameter resembles the type which is to be extended, preceded with the 'this' keyword. The arguments that follow are the actual arguments/parameters to the method.<br />
<br />
Another thing to remember is that extension methods should be defined as static members in a static class. The only difference between a normal method and an extension method is that the first parameter of an extension is always prefixed with the 'this' keyword. The rest are normal parameters. Also, when using the extension method you should remember to keep the extension method within the scope of its usage or you could even include it using the 'using' directive.<br />
<br />
<b>Usage Restrictions</b><br />
<ul style="text-align: left;">
<li>Extension methods can access only the public members of the type being extended.</li>
<li>If you define an extension method whose signature matches with the method already existing in the extended type, priority is given to the existing method and the new extension method is ignored.</li>
</ul>
Have fun with this great feature!<br />
<div>
<br /></div>
</div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-62094675305123827752012-01-29T15:06:00.003+05:302012-02-04T09:53:51.876+05:30C# 3.0 for Beginners - Extension Methods - Part 1<div dir="ltr" style="text-align: left;" trbidi="on">
All C# code is eventually executed by the .NET CLR. This requires the C# compiler to transform the LINQ query expressions to a format that is understandable by .NET. LINQ query expressions are transformed into method calls, which are called <b>extension methods</b>. These methods are slightly different from normal methods. Lets discuss them in more detail:<br />
<br />
Consider the example that we saw in my previous posts.<br />
<pre class="brush: csharp"> public static void GetIExplorer()
{
// 1. Data Source
Process[] processes = Process.GetProcesses();
// 2. Query Creation
IEnumerable<int> query =
from p in processes
where p.ProcessName.ToLower().Equals("iexplore")
select p.Id;
// 3. Query execution
foreach (int pid in query)
{
Console.WriteLine("Process Id : "+pid);
}
}</pre>
<br />
The query creation in part two transforms in a series of method calls on the data source 'processes' as follows.<br />
<pre class="brush: csharp"> IEnumerable<int> query =
processes.Where(p => p.ProcessName.ToLower().Equals("iexplore"))
.Select(p => p.Id);</pre>
<br />
The Select clause, however, it not essential. It may be ignored and you might retrieve a list of processes and not their process Ids. The Select clause here specifies the entity to be selected in detail, in the above example, it was the process id belonging to the selected process.<br />
<br />
Now, you might wonder that since the Where() method was called on the 'processes' Array, the Array object might have implemented the Where() method. But, that's not quite the case here. The method Where() is called an extension method and is used for extending a type's functionality.<br />
<br />
We have also made use of lambda expressions here. We will discuss their significance later in detail, but, for now, you can look at it as if it were a provision to select entities based in certain specified conditions. In the above code the variable 'p' indicates each element in the 'processes' array which is subjected to an expression evaluation (p.ProcessName.ToLower().Equals("iexplore")), and only if the result of the condition evaluation is true, will the item be selected as the result of the query. These are filtering expressions.<br />
<br />
In my next post I will describe how to define and use your own extension methods.<br />
<div>
<br /></div>
</div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-39524781312335337242012-01-29T14:57:00.000+05:302012-02-04T09:54:49.095+05:30C# 3.0 for Beginners - Query Execution in LINQ<div dir="ltr" style="text-align: left;" trbidi="on">
The execution of queries written is different from what a new LINQ user would perceive it to be. The query isn’t evaluated and the result is not stored in the query variable until the foreach iteration (where the values are actually required) or a manual iteration using the underlying GetEnumerator and MoveNext methods. The query variable only stores the query commands. This is concept is referred to as deferred execution.<br />
<pre class="brush: csharp">public static void GetIExplorer()
{
// 1. Data Source
Process[] processes = Process.GetProcesses();
// 2. Query Creation
IEnumerable<int> query =
from p in processes
where p.ProcessName.ToLower().Equals("iexplore")
select p.Id;
// 3. Query execution
// This is the part where the query is evaluated
// and result is stored in the query variable.
foreach (int pid in query)
{
Console.WriteLine("Process Id : "+pid);
}
}</pre>
<br />
As the query variable doesn’t store the results, you can execute it as many times as you like. If a data source is updated at regular intervals, you could retrieve the latest results every time you iterate over the query variable.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTCeqaDSUg-KeYlM7YiPTppEs3iqEXFuCkm1fDshgr2fn1sj8vz5DzVFtDxklJdu-8Z-G0zG1WpaB2Qo0h5V-x725yzNGMOZ7CoX1B5x2oFDLmD0N2unMR_LXvn_HP3frM6CzVn4hS_Ro/s1600/Deferred+execution.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="145" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTCeqaDSUg-KeYlM7YiPTppEs3iqEXFuCkm1fDshgr2fn1sj8vz5DzVFtDxklJdu-8Z-G0zG1WpaB2Qo0h5V-x725yzNGMOZ7CoX1B5x2oFDLmD0N2unMR_LXvn_HP3frM6CzVn4hS_Ro/s640/Deferred+execution.JPG" width="640" /></a></div>
<br />
The figure shown above shows information about the query variable ‘query’. The Results View section shows the results of query execution and it also informs the user that “<b>Expanding the Results View will enumerate the IEnumerable</b>” i.e. perform the query execution for debugging.<br />
<br />
<b>Forcing immediate execution of queries</b><br />
Immediate execution of queries is forced for queries that perform aggregation functions over the data retrieved from query evaluation. These functions include Count, Max, Min, Average etc. These queries execute without an explicit foreach statement because the query itself would use a foreach statement to calculate the result.<br />
<br />
The following query returns the number of processes identified as “IExplore.exe”.<br />
<pre class="brush: csharp">// Calculate the number of "iexplore" processes
int numberOfProcesses = query.Count();</pre>
<br />
Execution results can be cached (if need be) for temporary processing using the ToList() and ToArray() methods as shown below:<br />
<pre class="brush: csharp">// Caching results using ToList() and ToArray() methods.
List<int> queryResult =
(from p in processes
where p.ProcessName.ToLower().Equals("iexplore")
select p.Id).ToList();
Array inferredQueryResult =
(from p in processes
where p.ProcessName.ToLower().Equals("iexplore")
select p.Id).ToArray();</pre>
<br />
<br /></div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-53360626024746791702012-01-29T14:47:00.000+05:302012-02-04T09:55:41.577+05:30C# 3.0 for Beginners - Learning LINQ - An Overview<div dir="ltr" style="text-align: left;" trbidi="on">
I’m probably quite late to provide an overview on LINQ, which is by now a lot more popular than the time when I actually had started hearing about it.<br />
<br />
Well, this is expected to be a series of posts that would help other rookies like me who haven’t yet started learning LINQ yet. So, lets get started. To begin with I’m providing here an overview of LINQ (Language Integrated Query).<br />
<br />
LINQ was introduced by Microsoft with the objective to reduce the complexity of accessing and integrating information. With the LINQ project, Microsoft has added query facilities to the .Net Framework that apply to all sources of information, not just relational or XML data. Everyday programmers write code that accesses a data source using looping and/or conditional constructs etc. The same constructs can be written using query expressions that are far lesser in code size. LINQ makes it possible to write easily readable and elegant code. The examples that follow will imply how easily understandable LINQ code can be.<br />
<br />
LINQ defines a set of standard query operators that you can use for traversal, filter and projection operations. These standard operators can be applied to any IEnumerable<T> based information source. The set of standard query operators can be augmented with new domain-specific operators that are more suitable for the target domain or technology. This extensibility in the query architecture is used in the LINQ project itself to provide implementations that work over both XML (LINQ to XML) and SQL (LINQ to SQL) data. Lets write some code to understand the query operators in more detail:<br />
<pre class="brush: csharp">using System;
using System.Collections.Generic;
using System.Linq;
using System.Diagnostics;
/// <summary>
/// Using standard query operators.
/// </summary>
public static void GetIExplorer()
{
// 1. Data Source
Process[] processes = Process.GetProcesses();
// 2. Query Creation
IEnumerable<int> query = from p in processes
where p.ProcessName.ToLower().Equals("iexplore")
select p.Id;
// 3. Query execution
foreach (int pid in query)
{
Console.WriteLine("Process Id : "+pid);
}
}</pre>
<br />
All LINQ query operations consist of three distinct operations:<br />
<br />
<b>Identify the data source</b><br />
<b>Query creation</b><br />
<b>Query execution</b><br />
<br />
Calling the method would show you the currently running Internet Explorer processes (their process ids). The heart of the method lies in the following statement of our program.<br />
<pre class="brush: csharp">IEnumerable<int> query = from p in processes
where p.ProcessName.ToLower().Equals("iexplore")
select p.Id;</pre>
<br />
The expression on the right hand side of this statement is called the query expression. The output of this expression is held in the local variable ‘query’. The query expression operates on one or more information sources by applying the query operators from the standard or domian specific set of query operators. We have used standard query operators here namely where and select.<br />
<br />
The from clause select the list of processes which becomes the input for the where operator which filters the list and selects only those elements that satisfy the condition specified with the where operator. The selected elements are then processed by the select operator that determines any specific information selection for each element.<br />
<br />
The above statement can also be written using explicit syntax as shown below:<br />
<pre class="brush: csharp">IEnumerable<int> query = Process.GetProcesses()
.Where(s => s.ProcessName.ToLower().Equals("iexplore"))
.Select(s => s.Id);</pre>
<br />
This form of query is called a method-based query and the arguments to the query operators are called lambda expressions. They allow query operators to be defined individually as methods and are connected using the dot notation. I will deal with lambda expressions in my following posts.<br />
<br /></div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-12479987821956569012012-01-29T14:38:00.000+05:302012-02-04T09:56:22.126+05:30Anonymous methods in C#<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
An anonymous method is just a method that has no name. Anonymous methods are most frequently used to pass a code block as a delegate parameter.<br />
<br />
Before C# 2.0, the only way to declare a delegate was to use named methods as shown in the example below<br />
<br />
<pre class="brush: csharp">// Create the delegate
public delegate void Display(string message);
// Create the method
public static void DisplayOnConsole(string myMessage)
{
Console.WriteLine(myMessage);
}
public static void Main(string[] args)
{
// Here, the delegate is instantiated with the
// method which should be invoked.
Display myDisplay = new Display(DisplayOnConsole);
// Invoke
myDisplay("Hello World!");
}</pre>
<br />
Then C# 2.0 introduced the concept of anonymous methods.<br />
<br />
<pre class="brush: csharp">// Creation of delegate with an anonymous method
Display newDisplay = delegate(string msg)
{
// Anonymous method body
Console.WriteLine(msg);
};
// Invoke
newDisplay("Hello World using Anonymous methods.");
</pre>
<br />
The difference here is quite apparent. Creation of a new method to act as a handler is not required; the delegate itself specifies what should be done when invoked. Anonymous methods reduce the coding overhead in instantiating delegates because you do not have to create a separate method. Specifying a code bolck instead of a delegate can be useful in situations where creation another method might seem an unnecessary overhead.<br />
<br />
Some other points to remember:<br />
<ul style="text-align: left;">
<li>There cannot be any jump statements like goto, break or continue inside the code block if the target is outside the block and vice versa.</li>
<li>The scope of parameters of an anonymous method is the anonymous code block.</li>
<li>No unsafe code can be used within the anonymous code block.</li>
<li>The local variables and parameters whose scope contains an anonymous method declaration are called outer variables of the anonymous method. </li>
</ul>
<br />
In the following code the variable x is an outer variable.<br />
<br />
<pre class="brush: csharp">int x = 0;
Display newDisplay = delegate(string msg)
{
Console.WriteLine(msg + x);
};</pre>
<ul style="text-align: left;">
<li>An anonymous method cannot access the ref or out variables of an outer scope.</li>
</ul>
C# 3.0 introduces lambda expressions which are pretty much similar to anonymous methods but more expressive and concise. Applications written using .NET Framework version 3.5 and higher should make use of lambda expressions instead of anonymous methods. I will discuss lambda expressions in detail after I start with LINQ (Language Integrated Query) in my following posts.<br />
<br /></div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com1tag:blogger.com,1999:blog-4585959995852689823.post-7758369016994424552012-01-29T14:28:00.002+05:302012-02-04T09:57:05.268+05:30Did you know the two uses of ‘default’?<div dir="ltr" style="text-align: left;" trbidi="on">
Well, maybe you do and maybe you don’t. And I’m not trying to start a series of posts tagged “Did you know?”, I guess Sara Ford is much better at it.<br />
<br />
You’ve used the default keyword in C# as many times as possible in switch statements to indicate the default operation to be carried out. That’s one place where you would normally use the default keyword.<br />
<br />
You can also use the default keyword in generic code where it specifies the default value of the type parameter which is null for reference types and zero for value types. In generic programming it is always difficult to guess what default value to assign to a parameterized type T when you don’t know information such as whether T is a value/reference type; if it’s a value type, is it an elementary type or a struct? This is where the default keyword is used to find out the exact default value for the current type. Here is how it would be used:<br />
<br />
<pre class="brush: csharp">class MyGenerics<T>
{
public void MyMethod()
{
T myVar = default(T);
//...
//...
int defaultValue = default(int);
}
}</pre>
<br />
The default value for reference types is null, for value types is zero and for struct types each member is initialized with it’s default value depending on whether it is a value or reference type.<br />
<div>
<br /></div>
</div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-47284400158156928932012-01-29T09:33:00.004+05:302012-01-29T09:42:42.734+05:30Conditional compilation in C#<div dir="ltr" style="text-align: left;" trbidi="on">Programmers need to debug, which sometimes requires identification of points in your program where a programmer would like to insert code that would help him/her to debug his/her code efficiently. A simple example might be inserting a Console.Writeline() call that prints out values or indicates completion (successful or unsuccessful) of the executed part. However, these lines can clutter up the code structure and also needs removal of the debugging code for the release of the entire software.<br />
This overhead is taken care of by specialized methods in C# that help the programmer debug the code without the need to clean up his/her debugging code for the release phase. These methods which are used for debugging are called <b>Conditional methods</b>. The compiler identifies these marked methods and never includes them in the release build.<br />
Well, that’s good enough. But, how do I make a method conditional? .NET provides an attribute <b>System.Diagnostics.ConditionalAttribute</b> (alias Conditional) to achieve this. Let’s look at some code now.<br />
<br />
<strong>Defining the conditional method</strong><br />
<pre class="brush: csharp">public class MyTracer
{
[Conditional("DEBUG")]
public static void LogThisMessage(string myMessage, int severity)
{
// Write message to screen or a file or ...
Console.WriteLine(" DEBUG MESSAGE : " + myMessage +" SEVERITY LEVEL : "+severity);
}
}</pre> <br />
The Conditional attribute has been applied to the LogThisMessage() method with the <b>DEBUG</b> conditional compilation symbol. This signals the compiler that the method should be ignored if the conditional symbol <b>DEBUG</b> is not specified. <br />
<br />
<b> Using the conditional method </b><br />
With the <b>Solution Configurations</b> set to Debug mode if you execute the following code, you would happily see the output window shown below. <br />
<br />
<pre class="brush: csharp">public static void Main(string[] args)
{
// Some error occured in my code
// Log the message
MyTracer.LogThisMessage("The error 1221 has occured.", 5);
}</pre><div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqAq3ckifa1XrilToIzQeJGb4R5N5fV7viHV8-InLyckAY8sblMLBDXxcUNBSRR24nduXCJEav8_NAx5e1v2F_b01LG2wvrxedPoiHmRro_frKi0s9IX-CVpESEW_nQ9_wytpET0sSfTc/s1600/Conditional_Methods_DEBUG.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqAq3ckifa1XrilToIzQeJGb4R5N5fV7viHV8-InLyckAY8sblMLBDXxcUNBSRR24nduXCJEav8_NAx5e1v2F_b01LG2wvrxedPoiHmRro_frKi0s9IX-CVpESEW_nQ9_wytpET0sSfTc/s400/Conditional_Methods_DEBUG.JPG" width="400" /></a></div><br />
Now lets see what happens to our conditional code in the Release mode. To enable Debug or Release mode you have to look for the Solution Configurations selector in your Visual Studio IDE which is shown below.<br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvMHidKGNlVakxfgYIAc_MJnotH_Gwgb0WQ563QlL0NOP2rv9EaoMBmjS-MqJJNFwLJDmN_b0qsP8hh0zwgICLy9r0FFzYMaPg-rmPaI9eYh4HQUAW-GC_gygScHDtBHEF2jef5qAGr7Q/s1600/Solution_Configurations_Mode.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvMHidKGNlVakxfgYIAc_MJnotH_Gwgb0WQ563QlL0NOP2rv9EaoMBmjS-MqJJNFwLJDmN_b0qsP8hh0zwgICLy9r0FFzYMaPg-rmPaI9eYh4HQUAW-GC_gygScHDtBHEF2jef5qAGr7Q/s400/Solution_Configurations_Mode.JPG" width="400" /></a></div><br />
Change the mode to “<b>Release</b>” and you would see that the conditional code now has disappeared. <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXBcnLYFKElM798FkSCAmuytH18jWSrvpbyPys2P69ircPSb8xkop0KeDd_Ul8LSHaPw55nxsV05S-VyhNRdDKWVcnSB-Opbei5Ww40ughqw_GaquVEmpv5BTjf9vT5xYm6dBP3_5Xku0/s1600/Conditional_Methods_ReleaseMode.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXBcnLYFKElM798FkSCAmuytH18jWSrvpbyPys2P69ircPSb8xkop0KeDd_Ul8LSHaPw55nxsV05S-VyhNRdDKWVcnSB-Opbei5Ww40ughqw_GaquVEmpv5BTjf9vT5xYm6dBP3_5Xku0/s400/Conditional_Methods_ReleaseMode.JPG" width="400" /></a></div> <br />
We used the predefined <b>DEBUG</b> compilation symbol in our code. You can have your own defined symbols and use them for conditional compilation. You can define custom compilation symbols in Project Properties -> Build tab -> General. Checkboxes have been provided to enable or disable the <b>DEBUG</b> and <b>TRACE</b> symbols. <br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiys5LcrXyd8B6l-_RueJkeQo_bIzfT-OQ8fumuCFZ0VfAxCu_yha27RBauv30bQysdmDOAW_ZmXWEEImUoo9qKhQYT8ob4A2DeikW5-GMTtn2CsjKH9xlzELY5pHJRp3E_BhB9rNc2jzk/s1600/ProjectProperties_Build_ConditionalSymbols.JPG" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="106" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiys5LcrXyd8B6l-_RueJkeQo_bIzfT-OQ8fumuCFZ0VfAxCu_yha27RBauv30bQysdmDOAW_ZmXWEEImUoo9qKhQYT8ob4A2DeikW5-GMTtn2CsjKH9xlzELY5pHJRp3E_BhB9rNc2jzk/s400/ProjectProperties_Build_ConditionalSymbols.JPG" width="400" /></a></div> <br />
.NET also provides two classes that provide similar functionality: <br />
System.Diagnostics.Debug <br />
System.Diagnostics.Trace <br />
These classes contain methods that can also be used for debugging if you do not need more specific custom methods. <br />
<br />
</div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-56247050074408625532012-01-29T09:25:00.002+05:302012-01-29T09:27:19.067+05:30Covariance and Contravariance in delegates<div dir="ltr" style="text-align: left;" trbidi="on">If you’ve used delegates while programming you probably know about covariance and contravariance in delegates that provide a degree of flexibility when you match method signatures with delegate types. <br />
<br />
<b>Covariance </b><br />
Covariance allows a method to have a more derived return type than what is specified in the delegate. This is just another view of polymorphism where you would specify a more generalized delegate that could be used by the objects deriving from the specified type. <br />
<br />
The following example shows an example where covariance comes into picture. <br />
<br />
<pre class="brush: csharp">class Fruit
{
}
class Apple : Fruit
{
}
class CovarianceExample
{
public delegate Fruit CreateFruit();
public static Fruit CreateGenericFruit()
{
return new Fruit();
}
public static Apple CreateApple()
{
return new Apple();
}
public static void Main(string[] args)
{
CreateFruit fruitCreator = CreateGenericFruit;
// This is also perfectly fine.
CreateFruit appleCreator = CreateApple;
}
}
</pre>The delegate CreateFruit defines a return type of type Fruitand the same is applied to a method having the type Apple as a return type. <br />
<br />
<b>Contravariance </b><br />
Contravariance allows a method to have parameters that are less derived than what is specified in the delegate type. <br />
<br />
<pre class="brush: csharp">class ContravarianceExample
{
public delegate void ProcessFruit(Apple myFruit);
public static void Process(Fruit myFruit)
{
Console.WriteLine("Fruit Processed.");
}
public static void Main(string[] args)
{
ProcessFruit processor = Process;
// Example of contravariance
processor(new Apple());
}
} </pre> <br />
The above method shows how a delegate is invoked with an argument that is more specialized than the one specified in the delegate. <br />
<br />
While its not always necessary to remember these terms, it is usually easier to remember these simple concepts when we remember the terms. I knew this was possible but I only came across these terms while browsing through MSDN documentation lately. <br />
<br />
Although I’m pretty sure almost everyone who’s worked with delegates has come across these terms at least once, I would like to hear from you if this post has filled two more words to your .NET vocab. </div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-61247276446961479552012-01-29T09:23:00.001+05:302012-01-29T09:23:18.374+05:3010 Things I do to code better<p>After being into the software development career for more than a year now, I feel I understand what is expected from a "Software Developer". There are a lot of things that need to be done, and they need to be done with care. I see everyday that a lot of developers around me take software development as a job-to-be-done and not as a passion. Anyways, I'm here to talk about what I, as a software developer do to write better code everyday. Here's the list: <br />   <br /><strong>Keeping my code clean</strong> <br />Clean code could be described as code that is easily readable, and at the same time quite understandable. Stuff like proper indentation of code and the related comments can make your code look delicious. <br />  <br /><strong>Writing comments</strong> <br />Clean code and better comments make everyone's life simpler. Good comments are those which describe the 'WHW' (what, how and why) you do a particular thing in your code, in the simplest possible way. I call it "The expected WHW". Explaining this shouldn't be like writing an essay. Comments should be highly precise. <br />  <br /><strong>Writing Pre-conditions</strong> <br />Your code doesn't always stay with you. Everyone in your team should understand the pre-conditions and context when invoking a particular method that you might have written. The method which is being called should clearly describe it's pre-condition. Pre-conditions can be something like "The Person object should be initialized by calling the Person.Init() method" or something like that. Here, if the object 'Person' wasn't initialized, it may result in errors when other developers use methods that use the 'Person' object. This step helps other developers to use your code effectively. <br />  <br /><strong>Loose coupling</strong> <br />I always use this design principle to stay on the safer side with regards to scalability and maintainability. Loose coupling enables you to define boundaries within your code structure, and helps make easier the testing of the code and handling later changes in the code. This is one thing a developer's architect or designer might have a say in, but as far as I am concerned, I do have the liberty to suggest better coupling structures, however, they are happily trashed if we foresee any problem. <br />  <br /><strong>Knowing your programming language well <br /></strong>I'm always stuck in this conquest of mastering the programming language I use for coding. I keep switching from C++ to C# and vice versa but, I don't really understand which one to choose as they both have their own supernatural powers. I love C# for its simplicity and it's always a pleasure to work with it on Visual Studio. I came across a guy (who has always been working in C++) lately who was using C# .Net and was doing some kind of string processing. He had written around 10 lines of code for splitting strings (the C++ way, character by  character) based on a few characters but, never did he know that there is already a method called String.Split() that was readily available for use. It is difficult to know everything in the very huge .Net Framework, but the more you know the better your life becomes. <br />  <br /><strong>Learning Tips and Tricks</strong> <br />I always try and learn new tips and tricks to use my development IDE (Visual Studio) in the best possible manner. These tips and tricks help you to perform faster. Consider using keyboard shortcuts rather than moving your hand to the mouse and then searching for the respective button to be clicked in the IDE. This reduces the time in interaction with the IDE and would give you more time to think about your code. I learn tips and tricks in coding i.e. how something could be done in the best possible way. <br />  <br /><strong>Using Source and Version control software effectively</strong> <br />Source and version control software sound like an unnecessary nightmare to a low-on-experience software developer. I've had great times with Rational ClearCase. It's annoying ways help me learn more about it. Although a merge always screws up my code, I love the concept of source and version control because it enables me to code without the fear of losing my previously written code by mistake. I'm still in the process of taming this wild animal called "ClearCase". <br />  <br /><strong>Following coding guidelines</strong> <br />I always try my best not to be cursed by my fellow developers for not following the coding guidelines. Adherence to these guidelines helps developers to understand the "The expected WHW" of your code. This in turn helps you keep the code clean. <br />  <br /><strong>Reviewing my code</strong> <br />I always perform a self review of the written code before sending it for a review to the other team members. Reviews help you identify defects in the code at an early stage. Defects might miss out ones attention but, it might get caught by someone who would look at the code in a different manner or it may be easier for someone who has been working on the same thing for a long time to point out the possible defects in the code. <br />  <br /><strong>Knowing the context</strong> <br />Last, but never the least, it is a must to understand the entire context of usage of your code especially when you are adding particular functionality to existing code. There's always a chance that your changes could affect and break other's code. Always consult the original developers who had written the earlier code and get your code reviewed from them to avoid unexpected and vexing results. <br />  <br />This is a compilation of some things that I think help me in learning to code better. Opinions may vary, and if you’re still reading, I would like to hear your opinion on this. What do you think are other things that developers need to take care of? </p> Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-29600394335649828662012-01-29T09:15:00.005+05:302012-01-29T09:20:23.454+05:30Dynamic bitsets not supported in C++ STL<div dir="ltr" style="text-align: left;" trbidi="on">It was annoying and frustrating to come across the fact that an essential feature was missing in the C++ STL library that I was using. I was writing code that would create a bit array of length ranging from 1 to anything like a thousand or say ten thousand. This needed to be dynamically allocated. So, if I said:<br />
<pre class="brush: cpp">bitset* b;
...
b = new bitset(number_of_bits); // somewhere in the program</pre>This would create a bitset of "number_of_bits" bits. This would have been cool, but, this isn't the way bitsets are supposed to be used. The usage of bitsets is quite rigid. They are based on templates which need the size of the bit array at compile time which is done something like this.<br />
<pre class="brush: cpp">bitset<1000> b; </pre>or <br />
<pre class="brush: cpp">bitset<1000> *b = new bitset<1000>(); </pre>Now, how does that help me? What if I need more than 1000 bits someday? I can't just give it the highest possible constant value. Everything would fail one day if the question of scalability arises. I don't understand why the folks who developed STL didn't have this in mind. They did it for all the other data structures but, couldn't do the same for bitsets? Why? The question might sound strange but, the answer to this might even be more strange.<br />
<br />
So, what's the solution? <br />
Use Boost libraries - which have their implementation of dynamic_bitset. Damn! I can't use Boost as the firm that I work for doesn't want to. <br />
Use vector<bool> and implement overload the bitwise operator to act on that. Well, that's as good as creating a new implementation for my own dynamic bitset. <br />
<br />
So, I've decided that I'll create my own dynamic version of <bitset> as the guys at MSDN forums told me to. </div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-8319664702797689742012-01-29T09:11:00.001+05:302012-01-29T09:11:50.264+05:30Phishing in the name of Midwest Airlines<p>What happens when you receive a very polite email from an airline company which tells you that you have booked a ticket somewhere across the globe and your credit card has been charged with $690? This doesn't sound strange if you've really bought the ticket on your credit card. What happens when you know that you haven't?</p> <p>This happened to my colleague recently. She received a mail from the phisher pretending to be the Midwest Airlines web service which thanked her for purchasing the ticket and informed her that her credit card account was charged with $690. Gosh! You should have seen the look on her face. I definitely can't describe it. It was a mixture of fear (the fear of losing $690, which is quite a large amount), confusion (the confusion of what should be done next) and curiosity (all said and done, she too is a techie, knows and is curious about this stuff). But it's kind of cool to study the behavior of people becoming  victims (or in this case, potential victims) of phishing.</p> <p>She gave me a shout across the desk and asked what she should do next. I informed her not to delete the mail (as I needed it as a real phishing example for posting on my blog, cruel thinking!) and inform the information security folks about this problem. And, I shouldn't have believed her on that. She deleted the mail and dreams of including snapshots of that mail and the attachments were destroyed. Anyways, you can find the pattern of the mail and the attachment in this article on CyberInsecure.com.</p> <p>The best part of it was when I asked her to forward the mail to me. She looked at me as if I was planning to learn phishing by using that Trojan as my tool. But, by the time I asked for it, the mail was long gone (the mail was a victim of the Shift+Del disaster).</p> <p>The attachment contains contains an exe file named E-ticket_[number].doc.exe which is a Trojan horse that steals information, including keystrokes, from the infected Windows PC and transmits that data to a server hosted in Russia. Now, that is something to take note of. Almost a year ago, this Trojan ripped off more than 1.6 million customer records from Monster Worldwide Inc., the company that operates the popular Monster.com recruiting Web site.</p> <p>Have you ever been phished?</p> Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-27644128398474274402012-01-29T09:08:00.001+05:302012-01-29T09:08:30.693+05:30ClearCase and My Uncontrolled Source<p>I had some really funny time working with the Rational ClearCase source control software yesterday.</p> <p>I'm not a regular ClearCase guy. In fact, I hate source control softwares. They're always a pain until you realize it's power. I've been working on ClearCase for like, five months or something, but, I still don't feel comfortable with it, especially when it's installed with Visual Studio 2005.</p> <p>Yesterday, I tried renaming a file from "abc.cpp" to "xyz.cpp". Some crap happened in there and BOOM!!, the file was gone. Nowhere to be seen neither in the Clearcase Explorer nor using Windows Explorer. My mouth was left open and my lungs deflated by the very thought of writing 1000 lines of code again. Where did the file go?? I don't know!</p> <p>The only thing I could think about then was to search for it. But how? Not manually through each directory, of course. Pop! I opened up Windows Explorer Search(which was unbelievably slow, considering the fact the my files were stored on a "high-speed" processing server connected by a "high-speed" network). Was it an attack by some freaky terrorist trying to destroy my valuable work? Windows search disagreed to my thoughts. Results showed that there a file named "xyz.cpp.04ac136e421d4108b617d79bf2aec045" in a directory called "lost+found". Now, what does that mean? Was my file lost?? Probably, it was, which is in turn very very strange and no one likes such surprises.</p> <p>Thanks anyways to ClearCase for preserving a copy of the file before it lost it and folks, remember, to take care of this when renaming files using Visual Studio which are managed by ClearCase. Did you have any such crazy experience?</p> Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-80985488415535785612012-01-29T08:48:00.008+05:302012-01-29T09:05:02.519+05:30Efficient XML processing<div dir="ltr" style="text-align: left;" trbidi="on">Nowadays, many developers deal with a lot of XML files everyday. These files can be anything ranging from uses in configuration, documentation, databases where they are used for data sharing, data transport or simplifying platform changes. These files can grow to a very large size and need to be processed in an optimized way.<br />
For example, while reading a configuration file, the module that reads the XML, iteratively reads the XML tag for the current XML Element and decides what processing it then has to do. A relatively large XML file would then contain a lot of different XML Elements(differed by their tags) that need to be checked each time you encounter an XML Element. <br />
A brute force algorithm ro achieve this would be to check for each XML tag by doing a string comparison using an if-else ladder. For now, your XML file contains just three tags - Config1, Config2 and Config3. Your code would look something like this: <br />
<pre class="brush: csharp">
class Caller
{
public void Call(string inputValue)
{
// Using the if-else ladder
if(inputValue.Equals("Config1"))
{
Method1();
}
else if(inputValue.Equals("Config2"))
{
Method3();
}
else if(inputValue.Equals("Config3"))
{
Method2();
}
}
} </pre> <br />
All works well. But, what if the number of XML tags that need to be handled grow each day. You will be handling "Config1" to "ConfigN" in the same way as you have did before - using the if-else ladder. And what if you have no control over the value of 'N'. That is when the processing time for each file increases and a need arises to check the efficiency of the code. String comparisons do take a lot of time and having so many string comparisons can ruin your code in terms of efficiency, maintablility and scalability. <br />
<br />
If you try to visualize the above code in terms of a map, you would see that: <br />
<br />
"Config1" maps to Method1() <br />
"Config2" maps to Method2() <br />
and so on... <br />
<br />
Here's when you know that it would be useful to modify your code to utilize the Hashtable class. Initialize the Hashtable object to store the <key, value> pair as <string, MethodHandlerDelegate> where the string object represents the XML tag input such as "Config1", "Config2" and so on... and the MethodHandlerDelegate is a delegate type that references the method that needs to be called. This can be done using an initializer method such as: <br />
<br />
<pre class="brush: csharp"> private delegate void MethodHandler();
private SortedDictionary<string, MethodHandler> stringToDelegateDict;
public Caller()
{
stringToDelegateDict = new SortedDictionary<string, MethodHandler>();
}
public void Initialize()
{
MethodHandler handler1 = new MethodHandler(Method1);
MethodHandler handler2 = new MethodHandler(Method2);
MethodHandler handler3 = new MethodHandler(Method3);
AddHandler ("Config1", handler1);
AddHandler ("Config2", handler2);
AddHandler ("Config3", handler3);
// All the handler methods are initialized here in the SortedDictionary.
} </pre><br />
Note that we use a SortedDictionary object here since we are aware of the types of the key and value that might be inserted into the Dictionary. This saves us from doing any unnecessary downcasting which we would need to do if we used a Hashtable. <br />
<br />
Using this approach, it can also be decided at runtime that which of the handlers need be present in the dictionary by using the following methods that add or remove a handler from the dictionary. <br />
<br />
Now, you can subscribe the handlers only when they will be needed. <br />
<br />
<pre class="brush: csharp"> // Adding a new handler
public void AddHandler(string inputValue, MethodHandler handler)
{
stringToDelegateDict.Add(inputValue, handler);
}
// Removing an existing handler
public void RemoveHandler(string inputValue)
{
stringToDelegateDict.Remove(inputValue);
}
</pre>When you encounter an XML tag now, use just make the same call that you did earlier like this: <br />
<br />
<pre class="brush: csharp"> Caller c = new Caller();
c.Initialize();
c.Call("Input1");
c.Call("Input2");
</pre>However, you change your Call method to have the following implementation. <br />
<br />
<pre class="brush: csharp"> public void Call(string inputValue)
{
// Get the delegate to the respective method.
MethodHandler mh = stringToDelegateDict[inputValue];
// Make the call.
mh();
} </pre><br />
This definitely makes life simple while dealing with changes in the XML tags, adding handlers for new tags, removing handlers for existing tags and providing the runtime support for the same. Now, any changes occuring to the XML format would need changes in the Caller.Initialize method. Here, the method handlers act as subscribers that can dynamically subscribe/unsubscribe for a particular event. <br />
<br />
Now, what if your design says that it needs to call both Method1 and Method2 to handle the tag “Config1”? In case you were using the OrdinaryCaller design, you would handle it something like this: <br />
<br />
<pre class="brush: csharp">public void CallModified(string inputValue)
{
// Using the if-else ladder
if (inputValue.Equals("Config1"))
{
Handler.Method1();
Handler.Method2();
}
else if (inputValue.Equals("Config2"))
{
Handler.Method2();
}
else if (inputValue.Equals("Config3"))
{
// The OrdinaryCaller.Call method needs to be changed like this.
Handler.Method3();
}
} </pre><br />
The problem with doing this is that you need to keep changing the code of the Call() method and also the main disadvantage is that you cannot change the behaviour of the Call() method at runtime. <br />
<br />
Here is where the concept of multicast delegates comes into picture. You slightly modify the AddHandler() method to support multicast delegates. This let you have any number of delegate methods as handlers of each tag. <br />
<br />
<pre class="brush: csharp">// Adding a new handler
public void AddHandler(string inputValue, MethodHandler handler)
{
// Check if the string key is already available...
if (stringToDelegateDict.ContainsKey(inputValue))
{
// If yes, create a multicast delegate
// and place it back there with the same key.
MethodHandler temp = stringToDelegateDict[inputValue];
temp += handler;
stringToDelegateDict.Remove(inputValue);
stringToDelegateDict[inputValue] = temp;
}
else
{
// else, simply add the handler.
stringToDelegateDict.Add(inputValue, handler);
}
} </pre><br />
Just call the AddHandler() method to subscribe a new handler and voila! You’ve got another handler working right where you wanted it. <br />
<br />
I felt that the above mentioned technique is just a better way of handling large XML files. I’m sure more cleaner options exist to do the same which I’m not aware of. What do you think? What can be a better and more efficient technique to do this?<br />
<br />
</div>Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-83699752159583109952011-02-19T20:26:00.001+05:302011-02-19T20:27:25.533+05:30Mosher’s Law of Software Engineering == Bullcrap<p>Mosher’s Law of Software Engineering – <strong>“Don’t worry if it doesn’t work right. If everything did, you’d be out of  a job.”</strong></p> <p>You probably have already come across this one and perhaps also have nodded in agreement. But, what you fail to see is that it is this kind of thinking that has reduced software development in India to a laughing stock. Not caring if it doesn’t work right is just an incentive for us to not stop being lazy. It’s sad, but true. Managers are just happy if the number of billable hours are high, even if you were doing crap all day. </p> <p>Frankly speaking, Indian software developers have just become brats. Till now, there has been far lesser competition for India from the rest of the world when it comes to delivering software at a low price. But now, things are changing. Developing nations around the world which can not only can deliver the same software at a low price but can also maintain far higher levels of quality are coming up, and they are doing it far better than we could possibly even think of. We seriously need to rethink and redesign the way we work if we want to stay in the race for a long time.</p> <p>Delivering working software will not make you lose your job. That’s like saying Superman would be hanged for saving the world. </p> <p>Mosher was a jerk.</p> Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-73414843461461037192010-11-22T01:30:00.003+05:302010-11-22T20:15:02.375+05:30Solving problems and making decisionsI've noticed that I usually go through a lot of trainings each year, have fun in those trainings and forget whatever happened. Trainings are definitely a cool way to interact with people other than our project staff. And if you possibly learn something new, that's a bonus. But, most trainings are just crap. C. R. A. P. I'm not here to rant about such a crappy training I've probably been through. It's just that we have a lot of fun in these trainings, but when you try to look back after a couple of years, the only thing that one would possibly remember is whether there was a hot chick present in the training class or not. So, I'm trying to write down the stuff that happened in the training - what we learnt and what we could've and whether it has affected my normal routine in any way. <br />
<br />
Lately, I was in a training called 'Problem Solving & Decision Making'. Sounds like bullshit. Kinda was too. I don't understand why my manager nominates me to these trainings. But, I'm also glad I went through this training as I met and socialized with a lot of interesting people, learnt a few things about myself and found out the difference between the 2007 me and the 2010 me. <br />
<br />
The day started off in panic mode. We were ready for our trainer (Mrs. Pallavi Mandrawadkar) to begin at 0815hrs and look who comes in - another trainer for the same course. It was funny, incredibly funny. For once, we thought the L&D department had screwed it all up. But, things were resolved soon enough and we finally came to know that there was another training organized for the same course in some other training room. Wow! It could have been a lot more awkward. <br />
<br />
One of the things that I realized during the second day of the training was that now I was a lot more comfortable with portraying who I was and what I could do. I did have a strong opinion in most of the discussions that we had as a group and I could see how different people thought about the same problem in different ways. That's that best thing about working in groups. The group's dynamic is so much important than anything else. Another super-important thing that I realized was that people were so easily embarrassed on going wrong. We did an exercise on a tool called 'Appreciative Enquiry' and the morons that we were, we understood the technique incorrectly and ended up doing half of the thing wrong. Embarrassing? Yes. But, we're here to learn and mistakes happen. <br />
<br />
I'm glad to have worked in an environment where although mistakes were frowned upon, it was never that bad. Everyone is given a chance to make things right. The fear of making mistakes makes you more and more paranoid and you cannot be at your best when you're paranoid (no gyan, simple funda). <br />
<br />
We also did another exercise where we had to build paper airplanes, market the item with a creative jingle and present/sing the jingle as an advertisement for the product. After wasting some time convincing what a 'jingle' means to the team members, I finally started to write a simple jingle while the other members of my group made the paper planes. They looked cool. The jingle was done and I needed a scapegoat who could sing that! Guess what? Nobody's willing to sing it! Well yeah, nobody wants to look like a fucking moron singing a nursery-rhyme-like jingle. But, C'mon it's just a frickin' training room with 15 people! And no offence to the ladies, but there were no hot chicks present too! (Most guys prefer not to act like douchebags in front of hot chicks. True fact.) I didn't want to do it because I had already done my share of presentations earlier and did not want to be termed as a "stage hogger". <br />
<br />
In all that commotion finally someone decided to get on there and do the presentation. I asked him to sing out the jingle nicely and do the regular advertising stuff (I've heard/seen a fair amount of jingles and I know the pattern quite well). But, this guy (the jackass that he is) went up there and started talking some crap that we hadn't even written down and stole Cadbury's Dairy Milk's tag line and used that in the ad. Obvious disappointment! The guy was so embarrassed, he just wanted to get out of there. No biggie. But then I thought to myself, would I let my group's work go to waste by staying quiet and not giving our original jingle even a single try? No can dosville baby doll! I decided I should give it a try myself and said, "Pallavi, we actually have an original jingle that the team has made. But, maybe he's just a wee bit embarrassed to sing it as it's a little funny. I'd like to give it a try". <br />
<br />
I went up to the center of the room and blurted it out! To my surprise, everyone liked it. Wow! It's such a great feeling that you get when your audience approves of your crappy material. Coming up with a jingle in 10 minutes is hard. Very hard. But, we did it! That made my day! <br />
<br />
The rest of the training went fine. Learned a lot, maybe, I can't remember.Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-17961259501783724652010-09-30T23:04:00.001+05:302010-09-30T23:10:07.161+05:30Ideas and their execution…<p>It’s fair to say that 80% of the ideas that pop up in my head everyday never get executed or reach any valuable form of realization. Reasons for that to happen can be anything from time and money budget constraints to utter disregard for the problem. Until the problem really poses a PROBLEM, I never try to solve it. Necessity is the mother of invention they say.</p> <p>Today, I came across a great mini-project idea to implement a distributed build system for C/C++ which by utilizing the resources of an idle/available PC would reduce the build times by a considerable amount. Our build at work takes about an hour to complete. It sucks, (Viola! a performance necessity!) and hence the invention. Well, someone else has already invented it. There are a lot of tools/products based on this. <a href="http://code.google.com/p/distcc/" target="_blank">distcc</a>, however looks really cool. Like so many of my other ideas, it may stay as just an idea and never be implemented. But, I seriously hope I give this one a try. The guys at work use a proprietary department-wide build system and there’s fairly less chance that such an idea be accepted easily. But, just for the heck of it I’m just gonna go try this concept and in the process (however short) learn some cool stuff.</p> <p>The line between making up ideas and realizing them into concrete objects which satisfy/solve a problem is definitely not fine. It takes incredible effort and fortunately, for the one who can withstand the temptations of the world, brings great rewards.</p> Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com0tag:blogger.com,1999:blog-4585959995852689823.post-30897055732159370672010-09-26T19:40:00.001+05:302010-09-26T19:40:09.860+05:30Taking the blame.<p>I’ve been meaning to write something for a while now and the blog feels kind of dead. Being a World Champion procrastinator, its no surprise I’ve successfully put it off for a long time now. So let me break this down and lets talk some unwise wisdom.</p> <p>Its no new thing that a lot of people piss me off. Those are mostly people who don’t agree with me. I *really* don’t like those people. But, I guess that’s what makes me what I am. And fortunately for my employer, it has been a good thing so far. What am I talking about here? Frankly, I don’t know too. I’m trying to figure that out as I write this <strike>shit</strike> blog.</p> <p>My workplace is a warzone. People point their guns right at you when you include their name during talks, in mails and other formal/informal conversations. Why the insecurity? It’s hard to answer that question in one straightforward line. Think about this – You’re a great software dev, highly appreciated for your work in the previous projects you’ve been in. You now enter a sub-par project where almost 70% of stuff is done the wrong way. A software project can easily become sub-par over a period of time. You just need a bunch of shitty jack-asses who don’t really care about the software being developed and just give them complete responsibility over most of the features in the software. What you get then is “shitty software”. I feel bad for all the shitty software that has been developed over the years. It gets no love, both from the guys who maintain it and the guys who use it.</p> <p>You don’t want the blame. You start pointing fingers at each other trying to be as secure as possible. Shit! Your friggin’ appraisal depends on that! And that’s the part I hate the most. People who screwed up the software in the first place are no longer here. So why are we blaming each other? Making things right is what needs to be done. But that never happens! All the hostility creeps me out. And yes, I’ve fallen victim to these insecurities lately and I too carry a huge gun around waiting for my next firearms combat.</p> <p><a href="http://lh3.ggpht.com/_7MwN2xBacyM/TJ9UNkzxNrI/AAAAAAAAB9k/YWVZojLDfNk/s1600-h/office_fight%5B4%5D.jpg"><img style="border-bottom: 0px; border-left: 0px; display: block; float: none; margin-left: auto; border-top: 0px; margin-right: auto; border-right: 0px" title="office_fight" border="0" alt="office_fight" src="http://lh4.ggpht.com/_7MwN2xBacyM/TJ9UOomikGI/AAAAAAAAB9o/m1tKCz-3b6I/office_fight_thumb%5B2%5D.jpg?imgmax=800" width="627" height="235" /></a></p> <p>But this is plain wrong. I don’t want to be hostile. I hate being that guy. I cannot blame people who screwed up my work because they’re not here anymore. Blaming them wouldn’t mean anything. Blaming anyone doesn’t mean anything. You’ve just got to agree that we screwed up and make the best of what you have. I love my software and I hate it when somebody tries to screw it up. I get mad at people and say stuff that I regret later. I want my work to be fun. Don’t screw it up please.</p> <p>When you’re new to the software development game, everything has to be perfect. “Perfect” gets a new definition after you spend some time developing software. And, as time passes you realize that every single decision you make today – big or small – will come to haunt you if you don’t put your heart into it in the first place. Don’t be the person who fires the blame rockets everywhere. Nobody likes such people. It even makes you look really childish.</p> <p><a href="http://lh4.ggpht.com/_7MwN2xBacyM/TJ9UPZ6HC2I/AAAAAAAAB9s/eiGmT1P9q38/s1600-h/images%5B3%5D.jpg"><img style="border-right-width: 0px; display: block; float: none; border-top-width: 0px; border-bottom-width: 0px; margin-left: auto; border-left-width: 0px; margin-right: auto" title="images" border="0" alt="images" src="http://lh3.ggpht.com/_7MwN2xBacyM/TJ9UQLkTYCI/AAAAAAAAB9w/oezLaPFpRos/images_thumb%5B1%5D.jpg?imgmax=800" width="217" height="233" /></a> </p> <p>I try to see these problems as opportunities that need to be worked on. Improving the software makes my work more and more fulfilling. I’ve got a great team of developers/testers who are pretty much dedicated to building a good product. Encouraging them to do the same makes my work twice/thrice/.. as easier. That makes me happy. There will be a few glitches along the way. But, I’m glad to know that we’ll survive.</p> Anonymoushttp://www.blogger.com/profile/00438822974098859404noreply@blogger.com4