Posterous theme by Cory Watilo

Filed under: c#

Finding redundant code in Visual Studio solutions.

In the early days of the development of toepoke.co.uk I didn't have any proper source control management (yeah I know, I know !)

Anyway the days of commenting out code whilst I try stuff out and using my own source control management system are long gone (thankfully!).

However I still have a lot of commented out code hanging around from those days and I really need to get rid of it and to tidy things up. Thing is there's load of files and I didn't fancy going through every single file, so I figured there must be an easier way.

I figured typically I'm commenting out multiple lines of (C#) code, along the lines of this:



//public void SomeLazyCommentedOutMethod()
//{
//}


So all we need to do is search for //{ or // { or basically // followed by anything with { at some point afterwards. Sounds like a regular expression search to me. Ordinarily my ability to build a regular expression from scratch extends to this. But thankfully even I can cope this one!

(:b)*(//)+([a-zA-Z0-9])*\{

Which breaks down to:

  1. (:b)* = Zero or more tabs or spaces, followed by
  2. (//)+ = One or more slashes (/), followed by
  3. ([a-zA-Z0-9])* = Zero or more letters or numbers, followed by
  4. \{ = followed by an opening curly brace ({).

So if you bob (:b)*(//)+([a-zA-Z0-9])*\{ into the Visual Studio Find In Files dialog (CTRL + SHIFT + F) and hit Find All you should find most of the areas where you've commented out code.

C#

c# find in files dialog

VB.NET

vb.net find in files dialog

I reckon you should be able to the same in Visual Basic.NET by replacing the // with ' (so (:b)*(')+([a-zA-Z0-9])*\{ ) - however I've not tried it.

Well I've tried (the C# version) on the toepoke.co.uk code and found 158 hits which on the up side means it's probably working, on the downside I've been a naughty boy !

Regards,
Team TP!

Simple example on using ForEach generic method

Working on toepoke today and I wanted to loop through a list of objects and sync up some properties, so I started off by looping through a normal foreachconstruct. I vaugely remember there was a ForEach method hanging off the intellisense for list objects, so a quick google revealed ... not much (granted I didn't do a extensive search ... I'm very much in the "Not on the first page ... I'll figure it out myself!" camp :-)). Anyway seems like a good opportunity for a blog.So what example to use as an illustration? What about a noddy Personobject with the following properties:

  • Name - useful for seeing what's going on
  • DOB - which we'll generate when create a list of Person
  • Age - which is the property we're going to loop around and calculate.

Which gives us the following noddy class:

 public class Person {
    public string Name { get; set; }
    public DateTime DOB { get; set; }
    public int Age { get; set; }
 }
 

We're going to drive this example through a unit test (see full excert below), but I'll just concerntrate on the relevant bits here.  So next up let's populate a list of people to create our test data.

 List people = new List() {
    new Person() {       Name = "Fred Flintstone", DOB = DateTime.Now.AddYears(-65) },
    new Person() { Name = "Homer Simpson", DOB = DateTime.Now.AddYears(-40) }
 };
 

Simple enough, couple of cases, one aged 65, the other aged 40.  Our simple ForEach will loop through and work out the age of each instance.  To do this we'll just take the DOB away from the current time to delivery the number of years.  The ForEbach method is simply a delegate (which in essence is just a function) which may or may not take any arguments.  Ours isn't taking any arguments (it's a simple example after all :-)).  The code looks like this:

 people.ForEach(
    person => {
       person.Age = (DateTime.Now - person.DOB).TotalYears();
    }
 );
 

Now we're working against a list of type Person which is the person => bit.  The right hand side inside the curly brackets is in basically a method created on the fly for the purposes of the ForEach method.  So in essence the above is saying "for each person in the list of person set the age to the total number of years between the person's date of birth and now".  Doesn't look to scary now does it :-)? The more observant of you will have noticed that TotalYears doesn't exist in a TimeSpan object.  And you'd be absolutely correct; sadly the TimeSpan object doesn't provide a TotalYears method because it's quite complex to work out due to leap years and ... erm ... other stuff that's hard to work out ;-).  So to help out with our example, it's time for a little extension method on the TimeSpan class:

 public static class TimeSpan_Extensions {
    public static int TotalYears(this TimeSpan ts) {       return (int)ts.TotalDays / 365;
    }
 }
 

 

I would recommend you don't use that method for any production code whatsoever, I will guarantee bugs!  But it's perfect for our purposes.  Hopefully you've found this useful, and the full source is posted below, good luck and good searching.

   

 

 

 

 using System;
 using System.Text;
 using System.Collections.Generic;
 using System.Linq;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 namespace Blog.Tests {
    public static class TimeSpan_Extensions {
       public static int TotalYears(this TimeSpan ts) {
          return (int)ts.TotalDays / 365;
       }
    /// Summary description for ForEach
    [TestClass]
    public class ForEach {
       private class Person {
          public string Name { get; set; }
          public DateTime DOB { get; set; }
          public int Age { get; set; }
       }
    public ForEach() {}
     
    [TestMethod]
    public void Can_Calculate_Age_Using_ForEach() {
       List people = new List() {
          new Person() { Name = "Fred Flintstone", DOB = DateTime.Now.AddYears(-65) },
          new Person() { Name = "Homer Simpson", DOB = DateTime.Now.AddYears(-40) }
       };

       // Yup we could use ForEach here too, but I don't want to confuse what we know have to use (foreach) with what we don't (ForEach)! 
       foreach (Person p in people) {
          Assert.AreEqual(0, p.Age);
       }
       people.ForEach( a => {
          a.Age = (DateTime.Now - a.DOB).TotalYears();
       }
);        // element 0 is Fred Flintstone
       Assert.AreEqual(people[0].Age, 65);
       // element 1 is Homer Simpson
       Assert.AreEqual(people[1].Age, 40);
       people.ForEach( a => {
             TestContext.WriteLine(string.Format("Person ({0}, {1}, {2})", a.Name, a.DOB.ToShortDateString(), a.Age) );
          }
       );
    } // Can_Calculate_Age_Using_ForEach
    } // class ForEach
 } // Blog.Tes