Wednesday, December 31, 2008

C# is so much easier then C++

I have been given the opportunity to work on an old c++ program for work this last couple works.  I just have to say that C# is so much easier to follow and understand then MFC any day of the week.  I did learn how to check if a directory exists before creating it though.

 1569 if(GetFileAttributes(_T(tPath)) == INVALID_FILE_ATTRIBUTES)
 1570     {
 1571         SECURITY_ATTRIBUTES sa;
 1572         sa.nLength = sizeof(SECURITY_ATTRIBUTES);        
 1573         sa.lpSecurityDescriptor = NULL;
 1574         sa.bInheritHandle = FALSE;
 1575         CreateDirectory(_T(tPath),&sa);
 1576     }

Just thought I put this here for when I need it again.

Wednesday, December 10, 2008

Delimiters

Let’s talk about string delimiters and why you shouldn’t hard code them. Take the following example.

   16 return String.Format("#Command#{0}#{1}#{2}#{3}#{4}#{5}#{6}#{7}#{8}#{9}", completePath,
   17                                                                       GUID,
   18                                                                       UID,
   19                                                                       otherinfo,
   20                                                                       option1,
   21                                                                       displayText,
   22                                                                       filter,
   23                                                                       someint.ToString(),
   24                                                                       file,
   25                                                                       seckret);

It and three other ones just like it can be found in the code I am currently working on. Now when you see this you think that isn’t all that bad. Until you need to change the delimiter for one reason or another. You could go with something like the following but it not the most readable thing you will ever see.

   28 return String.Format("{10}Command{10}{0}{10}{1}{10}{2}{10}{3}{10}{4}{10}{5}{10}{6}{10}{7}{10}{8}{10}{9}",
   29                                                                       completePath,
   30                                                                       GUID,
   31                                                                       UID,
   32                                                                       otherinfo,
   33                                                                       option1,
   34                                                                       displayText,
   35                                                                       filter,
   36                                                                       someint.ToString(),
   37                                                                       file,
   38                                                                       seckret,
   39                                                                       commandStringDelimiter);

This is a little better now you can just change “commandStringDelimiter” to a different value when you need to change the delimiter. But it’s not verry readabel a better soluction is to do build a function that can build the string for you. This allows you to hide how it is created and keep it all in one place. Like this.

   54 public string BuildFileCommandString(params string[] options)
   55         {
   56             List<string> cStr = new List<string>();
   57             cStr.Add("Command");
   58             cStr.AddRange(options);
   59             return this.commandStringDelimiter + string.Join(this.commandStringDelimiter, cStr.ToArray());
   60         }      

You would call it like this.

   41 BuildFileCommandString(completePath,
   42                        GUID,
   43                        UID,
   44                        otherinfo,
   45                        option1,
   46                        displayText,
   47                        filter,
   48                        someint.ToString(),
   49                        file,
   50                        Seckret);

You will also notice that I used a string.Join rather then a string.Format this just makes it more readable to me.

Wednesday, October 29, 2008

Cool if statement.

I ran into this little if statement while fixing moving some code around today. It does something like 18 string functions and that is assuming that Path.GetExtension is just one string function call.

   30 if (Path.GetExtension(path).ToLower() == ".tif"
   31     || Path.GetExtension(path).ToLower() == ".pdf"
   32     || Path.GetExtension(path).ToLower() == ".jpg"
   33     || Path.GetExtension(path).ToLower() == ".png"
   34     || Path.GetExtension(path).ToLower() == ".gif"
   35     || Path.GetExtension(path).ToLower() == ".jpeg")

I decided that it needed to be removed and I replaced it with this.

   25 string ext = Path.GetExtension(path).ToLower();            
   26 List<string> validExt = new List<string> { ".tif", ".pdf", ".jpg", ".png", ".gif", ".jpeg" };
   27 if(validExt.Contains(ext)) 

But you could also do  this with LINQ

   25 var extensions = new List<string> { ".jpg", ".jpeg", ".tif", ".png", ".gif" };
   26 if ((from i in extensions where i == Path.GetExtension(dir).ToLower() select i).Count() > 0)

I like the second version the best but that is just personal preference.  Both alternatives are way better then the first option.

Tuesday, October 28, 2008

Fun with directory security

So for the last couple weeks we have been having a problem with our installer and it’s setting of access rights on directories. This was mostly a problem with vista and well I got made the “vista access rights expert” so that translates into you get to figure out what is wrong.

   15 static void Main(string[] args)
   16 {
   17     string aPath = @"C:\ProgramData\TestApp";
   18     string fPath = Path.Combine(aPath, "files");
   19     Directory.CreateDirectory(fPath);
   20     SetPermissions(aPath);            
   21 }
   22 public static void SetPermissions(string dir)
   23 {
   24     DirectoryInfo info = new DirectoryInfo(dir);
   25     DirectorySecurity ds = info.GetAccessControl();            
   26     ds.AddAccessRule(new FileSystemAccessRule(@"BUILTIN\Users", 
   27                      FileSystemRights.FullControl,
   28                      InheritanceFlags.ContainerInherit,                            
   29                      PropagationFlags.None,
   30                      AccessControlType.Allow));
   31     info.SetAccessControl(ds);            
   32 }

The code started out looking something like this. It adds a security rule for all users to the folder allowing use users access to data on the local system. Problem is that if a program tries to access the files it throws an access denied error. Even though the user’s effective permission to the folder is FullControl. He doesn’t have any access to the files in the folder, and can’t access the files dir at all. After several hours of reading and trying different things all the smart people I drug into help me with the problem came up with three small changes that make it all work without a problem.

   15 static void Main(string[] args)
   16 {
   17     string aPath = @"C:\ProgramData\TestApp";
   18     string fPath = Path.Combine(aPath, "files");
   19     Directory.CreateDirectory(aPath);
   20     SetPermissions(aPath);
   21     Directory.CreateDirectory(fPath);
   22 }
   23 public static void SetPermissions(string dir)
   24 {
   25     DirectoryInfo info = new DirectoryInfo(dir);
   26     DirectorySecurity ds = info.GetAccessControl();
   27     ds.AddAccessRule(new FileSystemAccessRule(@"BUILTIN\Users",
   28                      FileSystemRights.FullControl,
   29                      InheritanceFlags.ObjectInherit |
   30                      InheritanceFlags.ContainerInherit,
   31                      PropagationFlags.None,
   32                      AccessControlType.Allow));
   33     info.SetAccessControl(ds);
   34 }

The changes that needed to be made wore creating the base directory and setting permissions before the sub folder was added. In the set permissions folder there was also a second flag added to the inheritance option of FileSystemAccessRule that changed it so that both files and folders inherited the settings.

Monday, October 6, 2008

The DAO Class

In the project I am currently working on we have lots of objects and each object has it's own DAO class.  This is fine every class should have a DAO object.  Or I should say that there should be a DAO object that every class can use to access it's data from it's storage location. The thing is that most systems I have worked with don't do it this way.  They have a DAO object that creates objects.  Not objects that use the DAO system to create them selves.

I will give you an example.  Say you have a class called foo and you want to get an instance of it from the database. With the DAO as create system you have to do the following.

   20 foo bar = fooDAO.GetFooByID(fooID);



bar gets created in the fooDAO object so basically any place where you want to work with foo you have to have fooDAO around and visible in scope as well.  No in the way I like to see things like this done a foo object has a reference to the fooDAO in his class so when you are creating the foo object you just say:




   19 foo bar = new foo(fooID);



So some people will say you haven't accomplished all that much by pushing it down into the class.  Which is true you still have the same amount of code, but when the guy that writes the business logic is working with foo now he doesn't have to know about fooDAO or care about it. He gets to make calls like.




   22 bar.Save();



rather then calls like this.




   23 fooDAO.UpdateFoo(bar);



Then when the day comes where it is time to stop using the cheep read free database you decided to use and switch over to a more powerful database. All of your updates can be done one place for each class type, and if you designed it right and use an well defined interface for your DAO object you will be able just to change the DAO object reference in each class.

Wednesday, October 1, 2008

Best varible name ever.

So today I was looking at a coworker’s code. I am doing CURD processes for the system I am working on this isn’t creative code or even variable code beyond you change the names of what you are keeping in the database. But while grabbing his code to use as a template for the new function I ran across this little pearl of code. My work went from boring to enjoyable in second all because of one line of code that made me laugh. Her it is.


  716 object of_my_affection = command.ExecuteScalar();


Sometimes having a bit of fun in your code makes it better than all the naming conventions you could ever use.

Friday, September 26, 2008

Returning the comparison results

Over the last couple weeks I have been looking at some of my old code as well as going over other peoples projects. A personal pet peeve of mine keeps popping up in the code the worst part is when I started out programming I did the same thing. It’s when you do a Boolean comparison then return true or false rather than just returning the results of the comparison. Below is an example of what I am talking about.

   21 if (foo == otherFoo)
   22 {
   23     return true;
   24 }
   25 else
   26 {
   27     return false;
   28 }


The above is an example of what not to do. There have been many times in my life where I have done this not thinking about what I was doing. I am glad to say that time has passed. I have talked to others about it and they say they do it because it is more explicit and easier to read. I have a hard time agreeing with this stance how can the above be easier to read then the following.


   21 return foo == otherFoo;  


It’s short simple and easy to read.

Friday, September 19, 2008

Adding unique items to a list the fun way


In some of the work I do I have to combine several lists into one list and only add a item if it is unique by some arbitrary rule. I have done this so often in the last month I was about to write a code snipit for it. Then I started learning about template functions and realized I could just make one function to do this for me. I started out using Contains(vale,IEqualityComparer<>) to see if the item was already in a list this was a lot of effort and I never did figure out how to make a IEqualityCompare delegate. But there is this nice little method on lists called Exists which takes a predicate for comparisone. Which solved all my problems. The extention function I came up with seen below is probaly my favrite so far.

36 public static void AddIfUnique<T>(this List<T> tList, T toInsert, Func<T,T,bool> func)
37 {
38    if (!tList.Exists(p => func(p,toInsert)))
39    {
40        tList.Add(toInsert);
41    }
42 }


The usage for it is as follows.

15 DirectoryInfo mainDir = new DirectoryInfo(@"c:\");
16 List<FileSystemInfo> item = new List<FileSystemInfo>();
17 item.AddRange(mainDir.GetFiles());
18 DirectoryInfo mainDir2 = new DirectoryInfo(@"e:\");
19 List<FileSystemInfo> tList = new List<FileSystemInfo>();
20 tList.AddRange(mainDir2.GetFiles());
21 tList.ForEach(c => item.AddIfUnique(c, (k, j) => k.Name == j.Name));

In the above code the item list will end up with all file names that are unique. While this example is not the most useful example out there it does show how it works.

Tuesday, September 16, 2008

ForEach the functional way.


Before I started my current job I worked as a software tester and did a lot of automated testing in python. I love working in python it takes most of the effort out of programming you just write down what you want and it compiles and runs. Down side is python is not a strongly typed language and I picked up some very bad habits form python. Which others have proceeded to beat out of me. One thing that python did have that I truly miss is the map function. It makes working on lists so much cleaner, and when you mix that with lambda you come out being able to do a lot of work in very few lines of code. A couple weeks ago I was talking with a friend of mine about how C# had no map functions and how if I had it I could shrink a bunch of code down to next to nothing. The following functions are the results of that conversation. At the time I didn't want to return a list at the time I was doing a lot of file maintenance and just wanted to traverse the folder structures in a clean way. So llama being the guy he is emailed me these two functions.

12 public static void ForEach<T>(this IEnumerable<T> list, Action<T> func)
13 {
14     foreach (T t in list)
15     {
16         func(t);
17     }
18 }
19 
20 public static void ForEach<T>(this IEnumerable<T> list, Action<T> func1, Action<T, Action<T>> func2)
21 {
22     foreach (T t in list)
23     {
24         func2(t, func1);
25     }
26 }

Here is an example of how they can be used.

14 public static void WalkFiles(string filePath, Action<string> workerFunc)
15 {
16     if (WalkFilesCont)
17     {
18         if (Directory.Exists(filePath))
19         {
20             System.IO.Directory.GetFiles(filePath).ForEach(workerFunc);
21             System.IO.Directory.GetDirectories(filePath).ForEach(workerFunc, WalkFiles);
22         }
23     }
24 }

I use them in a lot of other areas I even have one variation that behaves like a map in python I don't do much work on lists though where I need to see a result passed back so it doesn't get as much use. These first function gets used quite a bit more than I expected.

Thursday, September 11, 2008

Programming the hard way


On several occasions in my short life I have ran across coders that insist on not using the prebuilt classes and functions that come with .net. I can understand not using a 3rd party lib when you write the entire product for the ground up, but if you are using .net you might as well use it to its fullest extent.
Take the following code:

 9    using (FileStream fs = new FileStream(FilePath, FileMode.Open))
10    {
11        using (BinaryReader br = new BinaryReader(fs))
12            rawTiffData = br.ReadBytes((int)fs.Length);
13    }
14    tiffData = Convert.ToBase64String(rawTiffData);
15 
16    string name = tiffPath.Substring(tiffPath.LastIndexOf('\\') + 1,
17        tiffPath.LastIndexOf('.') - tiffPath.LastIndexOf('\\') - 1);

It will open up a tiff file and read in all of the bytes and then convert it to base 64 encoding. Then he gets the name of the file without its extension. Let's do the same thing but using the .Net functions that should be used.

 9    rawTiffData = File.ReadAllBytes(this.FilePath);
10    tiffData = Convert.ToBase64String(rawTiffData);
11    string name = Path.GetFileNameWithoutExtension(this.FilePath);


The second section of code is almost self documenting. You can at a glance see what is going where and why. You also don't have to worry about getting your substring wrong or someone a year down the road coming in and making a small change to the substring call to make it better. Adding a bug that is not trivial to find.

Wednesday, September 10, 2008

Good code layout.

Recently I have been looking at and writing a lot of c# code. It's nice when you get paid to program in the language you want to learn. I have noticed in several places where people build the same complete object with one or two difference in two separate locations in the code usually a if else statement. I have a big belief in don't repeat yourself when programming. If you find you are writing the exact same code or close to it over and over again you are doing something wrong. Here is a good example of what I am talking about. It also isn't too far from the code that made me want to write this post.



String Foo1 = "3.4.5";
String Foo2= "3.4.6";
mObject boo = null;
if(new Version(Foo1) > new Version(Foo2))
{
    boo = new mObject
    {
        vLam = "yummy",
        jArp= "jello",
        cFile= "No"
    };
}
Else
{
    boo = new mObject
    {
        vLam = "yummy",
        jArp= "jam",
        cFile= "Yes"
    };
}

In the above code we see an example of what not to do. You are creating dynamic objects to make a decision that could be made using a string comparison operator which isn't really on topic but is worth mentioning. Also you have double the code you need in creating your object.


Now let's do it in the cleaner way that I would like to see one instantiation and then just assign the values as we go.



String Foo1 = "3.4.5";
String Foo2= "3.4.6";
bool isFoo2Less = Foo1.CompareTo(Foo2) > 0
mObject boo = new mObject
{
    vLam = "yummy",
    jArp= (isFoo2Less)? "jello" : "jam",
    cFile=(isFoo2Less)? "No" : "Yes"
};

We end up with less lines of code and even though we add a variable to the mix and do two checks. The maintainability of this code is much easier and will cause less confusion over the life of the program.