advanced web statistics

List.ForEach Method & Delegate Trick

Andrew Robinson sent out an e-mail to our local .NET group about anonymous delegates.  The e-mail got me interested and I started reading up on delegates in the 2.0 framework. I am currently working on a class for a project that uses a lot of Generic lists.  While enumerating these lists I need to make changes to the collection and of course I am unable to make direct changes to the collection while I am enumerating (rightfully so!).  The next logical thing to do is create a copy and make changes and after enumerating commit those changes to the collection.  This entailed creating a method such as CopyList that would take a parameter of List<T> or simply an Object.

Two weeks ago I had a method that looked like the following.

static List<Bar> CopyFoo(Foo item)
{
   List<Bar> foo = new List<Bar>();

   foreach (Bar bar in item.Bar)
      foo.Add(bar);

   return foo;
}

Pretty basic stuff. The method takes the Foo object and enumerates each Bar in item. Each Bar is added to another collection of Bar. Pretty simple and straight-forward.  As simplistic as that looks, there is actually an easier, and in my opinion; more elegant way.

With the Generic List ForEach method you can dump the entire contents of a collection in one line!

static List<Bar> CopyFoo(Foo item)
{
   List<Bar> foo = new List<Bar>();

   item.Bar.ForEach(delegate (Bar bar) {foo.Add(bar);});

   return foo;
}

Very simple but a cool trick nonetheless.  The action of the ForEach method is a delegate to a method that performs an action (List.Add) on the object (Bar) passed to it.

Tags: .NET, C#, Interesting, Programming

Coding Standards: How Important Are They?

Started reading a very interesting article this morning on the importance of coding standards. This article is particulary interesting to me because of the nature of the work that I do on a day-to-day basis: custom software development. Now while working in custom software development I have heard many conflicting thoughts and practices when it comes to standards. In a perfect world, I would agree with the camp that likes to have every developer stick to a certain set of standards and practices. Reality is that deadlines sometimes put a damper on doing things the right way.

How do you cope with this? I hate to start a project using standardized practices and then told to make shortcuts to meet a tight deadline. I know that custom software development is a little more fast-paced than an in-house development job, but I would assume that managers would put a priority on consistency. When the project is done and delivered I don`t care if the person that takes over my job thinks they could write better code. It is more important for me leave them with code that is easy to follow and make adjustments to. Consistency is key. 

Some of my "favorite" malpractices:

Technology Malpractice My Practice
SQL Server (table name) tbl_Mstr_Stdnt_Schdl MasterStudentSchedule
SQL Server (field) Univ_Crs_ID UniversityCourseId
.NET (variable) str_Stdnt_ID studentId
.NET (handler name) Button28_Click SubmitSchedule_Click

I know that there are those of you that would go about things in different ways.  Like the article above states, "Show me code written by ten developers and I'll show you ten different coding styles."  I think one thing we can all agree on is that the malpractices above are in no way excusable.

Some of you might notice that I use Id instead of ID. I have seen that the field seems to be split on this. I like to think of Id being a common enough convention that one not need to capitalize both letters, much like System.IO.

What are your thoughts?

Tags: Business, Development, Programming

Using SqlCommand Parameters with Multiple Inserts

I`ve received the following error today while working on a method that INSERTS multiple records into a database. I am using the SqlCommand class and parameterized queries. Keep in mind this is a simple vanilla insert, hence the lack of a SQL stored procedure.

The variable name `@dayId` has already been declared. Variable names must be unique within a query batch or stored procedure.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Data.SqlClient.SqlException: The variable name `@dayId` has already been declared. Variable names must be unique within a query batch or stored procedure.

The code below ( pseudo ) will give you the previous error.

private void UpdateDatabase(int dayId, string bar)
{
   using ( SqlConnection cn = connection )
   using ( SqlCommand cm = new SqlCommand("INSERT @dayId, @bar", cn) )
   {
      cn.Open();

      for ( int i = 0; i < 5; ++i )
      {
         cm.Parameters.AddWithValue("dayId", dayId + i);
         cm.Parameters.AddWithValue("bar", bar);
         cm.ExecuteNonQuery();
      }
   }
}

If you run into this same error when doing multiple inserts you simple need to clear your parameters after performing your ExecuteNonQuery().

private void UpdateDatabase(int dayId, string bar)
{
   using ( SqlConnection cn = connection )
   using ( SqlCommand cm = new SqlCommand("INSERT @dayId, @bar", cn) )
   {
      cn.Open();

      for ( int i = 0; i < 5; ++i )
      {
         cm.Parameters.AddWithValue("dayId", dayId + i);
         cm.Parameters.AddWithValue("bar", bar);
         cm.ExecuteNonQuery();
         cm.Parameters.Clear();
      }
   
   }
}

Easy. If I help only 1 person with this then I feel that I have done my job!

A little aside; I couldn't find any documentation for SqlCommand.Parameters.Clear() on MSDN. To me that seems strange.

Tags: .NET, C#, Code, Programming

Insert Expletive Here! Ooooops!

I woke up this morning and headed out to a client`s site.  Cold, wet morning.  To add a layer of excitement I am also getting over the flu.  Upon arriving I start writing code, importing data, making local copies, etc... Today I brought my trusty flash drive so that I can work from home tomorrow (Friday) and the rest of the weekend.  I figure everyone in the office (client site) will be gone so why should I have to show up?  After making sure I have all the necessary data I right-click my project folder, `Send To`, `Removeable yada, yada`.  I then click the `Safely Remove Hardware` button on the taskbar and wait for the prompt telling me that it is now `safe to remove` hardware.  And I`m off.

Now at home I just built a little stove fire and get ready to bang out some code when I realize that the code-behind for default.aspx.cs is completely wiped out and replaced with a partial javascript file from my Includes/javascript directory and the XML document (read schema) is now missing.

Guess what I`m doing tomorrow morning? Hopefully someone will be there. I will have to break the cardinal rule of network policy by telling someone my password over the phone. Great. It beats a 40-minute drive though.

F&&K! SH&T

So I probably could not recreate this in a million years if I tried.  Anyone have any stories like this?  I guess it could have been worse.

UPDATE: I'm back on track. That was close!

Tags: Interesting, Programming

Usefulness of SqlDataSource

using Microsoft.Corporate.Advertising.CoolDemos.Controls;

For your reading pleasure, see what Microsoft has to say about the SqlDataSource. The following excerpt has been taken from the "Working with the ASP.NET 2.0 ObjectDataSource Control" article on MSDN:

However, there is one problem with the SqlDataSource control. If you use the SqlDataSource control, then you are doing something bad. The SqlDataSource control is bad since the control forces you to jumble together your user interface layer with your business logic layer. Mixing layers, as any application architect will tell you, is just shameful.

What are your thoughts on the usefulness (or lack thereof) of the SqlDataSource control? What if your data is derived from stored procedures?

Side Note:
This entry inspired by the ReorderList control in the AJAX toolkit being populated by the SqlDataSource.

Tags: .NET, Programming

Refactoring in Visual Studio 2005

Working in the custom software development arena it is customary that projects and / or source code grow increasingly complex over time.  You are either adding extra "requirements" to existing code or inheriting less-than-ideal code (read kludgy).  Enter refactoring.  With refactoring you can reorganize the internal structure of the code without changing the public appearance or interface.

In Visual Studio 2005 there are quite a few new refactoring tools.  The list below are some of the more helpful and are limited to C# development. Sorry.

Encapsulate Field
This process turns a variable declaration into a public property. If nothing else this will save you a significant amount of typing. The property syntax is automatically generated.

Before:
private string foo;

After:
public string Foo
{
   get { return foo; }
   set { foo = value; }
}

Extract Method
Imagine inheriting source code for a project that has a 550 line Page_Load method. It's ugly. Not only does the method not fit on one screen, there is no way to possibly describe what the method does in one sentence or less. If you're like me you will find a need to granularize this method once you get somewhere between SqlDataReader reader2 and SqlDataReader reader15. Now enter the Extract Method in the Refactoring drop-down. All you need to do is highlight a large block of code that you want to granularize / extract into a child method and select 'Extract Method' from the Refactoring drop-down. Now simply type a name for this child method and it will appear below the parent. You are now one step closer to having granularized source code. Remember, it's easier to build something big out of many small components.

Parameter Refactoring
Over time methods that take parameters will change and as a result of that the number of parameters will change in one way or another whether a string is now passed or there are two integers being passed in instead of four. This is a nice maintenance method that can help you reorder your parameters. Let's say that you have a few common parameters such as projectId, employeeId, timeStamp. If you are like me then it is of utmost importance to make sure that those parameters are passed into a method in the same order everytime. The Parameter Refactoring tool will allow you to do that. Every reference to a parameter-refactored method will be updated accordingly. Easy.

What About VB?
Sorry folks. The same refactoring tools that C# developers can take advantage of aren't built-in to Visual Basic .NET. There is an add-on called Refactor! that will mimic C#'s refactoring functionality and then some. Peace to having to download an add-on.

Tags: Programming, Tools

String.Compare() versus String.Equals()

I don`t know how I stumbled upon this but I can say that I remember a co-worker getting aggravated because of someone performing string comparisons using an equals sign. He was very adamant about how simply comparing two strings using an = (or == for C# ninjas out there) is the craziest thing a programmer could do. "What if your application is sold to a company in Turkey?" he asked. After reading an article this morning on string comparisons I read about an example for string comparisons that introduced a bug when used in certain cultures; namely Turkish. After brushing up on my Turkish alphabet this morning I noticed that the lowercase "i" is much different than our lowercase "i". It actually looks like a lowercase "1".

string first = "ınfinite";
string second = "Infinite";

After reading this example I smiled to myself at how right this guy was. I have in the past ignored Globalization issues because my apps have always run in English cultures.  After today I will no-longer presuppose American Operating Systems or cultures.  It is very easy to retro-fit your existing code to accomodate culture-specific string comparisons.

Before I show you how I do that, it's time for me to take a trip down memory lane of bad programming practices; at least from an academic standpoint.

The Bad
private bool ValidString(string first, string second)
{
   if (String.Equals(first.ToLower(), second.ToLower()))
      return true;
   else
      return false;
}

The Badder
private bool ValidString(string first, string second)
{
   if (String.Equals(first, second))
      return true;
   else
      return false;
}

The Better
private bool ValidString(string first, string second)
{
   if (String.Compare(first, second) == 0)
      return true;
   else
      return false;
}

What if you create an application that is sold on a world-wide scale? Maybe it is sold to cruise lines that operate out of different countries, hotel/restaurant chain, etc... There is a possibility that your application will be put onto a server with different language and culture settings. This leads me to what I believe is the best way to approach string comparisons.

The Best
private bool ValidString(string first, string second)
{
   if (String.Compare(first, second, true, CultureInfo.CurrentCulture) == 0)
      return true;
   else
      return false;
}

The two strings are passed compared, the true is a boolean value for ignoreCase. In this case we are ignoring case-sensitive (read: case-insensitivity).  This example is ideal for making sure that the input value of "bob" is the same as "Bob" or "BOB". The CultureInfo.CurrentCulture is passing in the CurrentCulture settings. Easy enough.

Proof-of-Concept
Either create a new project or add the following to an existing project.  Add this method to your code-behind.  We are going to force the Turkish culture settings here to prove this point.

private void CompareStrings()
{
   string first = "ınfinite";
   string second = "Infinite";

   if (String.Compare(first, second, true, new CultureInfo("tr-TR")) == 0)
      Response.Write("true!");
   else
      
Response.Write("false!");
}

Add a button to your form and on on it's click event handler type:
CompareStrings();

I'd love to hear your thoughts on this. Good? Bad? Could do something better?

Update
Don't forget to use the System.Globalization namespace.

Related
String.Compare Method (String, String, Boolean, CultureInfo)

Tags: C#, Code, Programming

Optimistic Concurrency Issues

Optimistic concurrency is not fun at all.  We are currently working on a project that has 2 mothers.  By 2 mothers I mean there are 2 people CRUD`ing data at any given time.  Imagine one person executing a series of stored procedures that result in setting the PrintedFlag to 1 and someone coming behind you executing a set of stored procedures that result in setting the PrintedFlag to 0. ddd

What was happening was I was executing a series of stored procedures and someone else was coming in behind me and executing the same stored procedures before I was finished.  The simple solution was to use a StringBuilder and create SQL Transaction statements.

private void UpdateDatabase(XmlTextReader reader)
{
   // loops through an Xml file and builds a string
   StringBuilder sql = new StringBuilder("BEGIN TRANSACTION\r\n");

   while(reader.Read())
   {
      switch(reader.LocalName)
      {
         case"localName1":
            sql.Append("exec StoredProcedure1 ");
            sql.Append("@p1=" + Convert.ToInt32(attributes["one"]) + ",");
            sql.Append("@p2=" + Convert.ToInt32(attributes["two"]) + ",");
            sql.Append("@p3=" + Convert.ToInt32(attributes["three"]) + ",");
            sql.Append("@p4=" + Convert.ToInt32(attributes["four"]));
            sql.Append("\r\n");

            break;

         case"localName2":
            sql.Append("exec StoredProcedure2 ");
            sql.Append("@p1=" + Convert.ToInt32(attributes["one"]) + ",");
            sql.Append("@p2=" + Convert.ToInt32(attributes["two"]) + ",");
            sql.Append("@p3=" + Convert.ToInt32(attributes["three"]) + ",");
            sql.Append("\r\n");

            break;
      }
   }

   sql.Append("COMMIT\r\n");

   // this.cn is the application connection string
   using ( OleDbConnection cn = new OleDbConnection(this.cn) )
   {
      using ( OleDbCommand cm = new OleDbCommand(sql.ToString(), cn) )
      {
         cn.Open();
         cm.ExecuteNonQuery();
         cn.Close();
      }
   }
}

Tags: C#, Code, Programming, SQL

Adding CAPTCHA Functionality For Comments

I was getting spammed like crazy on a few posts.  That`s what I deserve for creating this blog engine half-assedly (word?).  When I first starting writing this blog it was mostly me posting stuff from work for reference.  Then it became more of a hobby. Apparently this content is very popular amongst the medical community.  People can`t stop offering me Viagra, Phentermine, Cialis, and Ambien.

Seriously though, I added a CAPTCHA to the reply page to stop these bots from running and spamming (splogging?) my entries.  The sample I based mine off of was on Code Project but if you are interested I can post my version. 

Very simple and basic.  Let`s see if it will last!

Tags: .NET, Interesting, Programming

File.Exists and Network Paths

What is up with the File.Exists() method in ASP.NET 1.1? I mean, I understand that this method takes a string parameter (aka the file to check) and that it will return true if the caller has required permissions and the path contains the name of an existing file; else false... This is easy to understand.

What I don't understand is why this method returns false everytime if you reference a network folder?

What I want to do

string pathExport = @"\\server\path\file.name";

if(File.Exists(pathExport))
{
   File.Move(pathExport, pathArchive);
}

There is a very ugly way to get around this but it would probably be frowned-upon from an academic standpoint. In theory I could just bypass the checking for the existence of a file and try to move it anyway. This can be accomplished with a Try Catch block.

try
{
   File.Move(pathExport, pathArchive);
}

catch ( Exception ex )
{
   UpdateLogFile("ERROR: " + ex.ToString());
}

Any way around this?

Tags: .NET, Programming
<< Newer Entries Older Entries >>