Thursday, February 14, 2008

My office mate Chad came up with yet an even better option. You need to be using 3.5 and include the System.Linq extension method namespace. It didn't perform quite as well but pretty close. Even more general purpose. Note that the default SequenceEqual method throws an exception when either operator is null so I handled those cases first.

bool Compare<T>(IEnumerable<T> left, IEnumerable<T> right)

{

    // handles the same array

    // handles both null

    if (left == right)

        return true;

 

    // fails when either are null

    if (left == null || right == null)

        return false;

 

    return left.SequenceEqual(right);

}

 

Andy | C# | LINQ
Thursday, February 14, 2008 3:02:02 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 

Slightly more efficient by starting off with a reference compare. If the same two arrays are passed in, no need to compare the elements. I don't think there is a better way unless you use unsafe code / pointers. The use of generics makes this more general purpose.

bool Compare<T>(T[] left, T[] right)

{

    // handles the same array

    // handles both null

    if (left == right)

        return true;

 

    // fails when either are null

    if (left == null || right == null)

        return false;

 

    if (left.Length != right.Length)

        return false;

 

    for (int i = 0; i < left.Length; i++)

    {

        if (!left[i].Equals(right[i]))

            return false;

    }

 

    return true;

}

 

Andy | C#
Thursday, February 14, 2008 1:03:17 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 

Here is a little code that I simplified:

public Boolean Compare(Byte[] a, Byte[] b)
{
   return(a=b);
}

Seems like it should work right?  Compare each Byte in a with the same Byte position in b and return if the two arrays have equal values in each position?  It doesn't do that -- it compares the two objects to see if they are equal.  My solution:

public Boolean Compare(Byte[] a, Byte[] b)
{
    if ((a == null) && (b != null))
        return (false);

    if ((a != null) && (b == null))
        return (false);

    if ((a == null) && (b == null))
        return (true);

    if (a.Length != b.Length)
        return (false);

    for (int i = 0; i < a.Length; i++)
        if (a[i] != b[i])
            return (false);

    return (true);
}
Is there a better solution?
{6230289B-5BEE-409e-932A-2F01FA407A92}

 

C# | Wayne
Thursday, February 14, 2008 8:50:49 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 

In working on some inherited code in a very large and complex website I was a little bit skeptical of touching the code.  Let's just say the codebase was dubious at best.  This presented a problem as I had 3 days to make a lot of changes in the admin section of the site.  When inheriting code there is always a learning curve.  Unfortunately I didn't have this luxury as I spent 1.5 days getting the code running locally (still haven't COMPLETELY finished this).  This left me with about another half-day to learn the handful of tables I was to be using.  One day to actually write the code.  No problem. 

So the client relayed to the PM what needed to be done which was ultimately relayed to me.  "When a manager selects a value from the whatever dropdownlist the values for the FileUpload control disappears and the user has to re-enter this value (which is by design as this would be a huuuuge security risk. Think if you could programmatically set the postedfile for the FileUpload control!).  Different sections are displayed depending on the value of such-and-such dropdownlist, etc..." I then ask myself, "WTF are there so many postbacks to simply hide / show sections?"  This sounded  like a perfect opportunity to utilize my new favorite property: Control.ClientID.  The goal was to move the functionality from server-side to client-side while making minimal changes to the server-side code ( VB* ;-) ). Half of the dropdownlists had AutoPostBack enabled.  I expected to see a handful of handlers when I viewed the code-behind. Nope. Why is it that developers feel the need to always post back to the server even if nothing is happening? Maybe they were planning to implement the handlers in the future?  A postback is kind of a big deal and I believe they should be used sparingly, but that is just me.  Anyway, my server-side code consisted of maybe 6 lines where I added Attributes to server-side controls similar to:

dropdownlist.Attributes.Add("onchange",

   string.Format("clientSide('{0}', '{1}', this.value)",

   someDiv.ClientID, anotherDiv.ClientID))

With ClientID I am shoving the ID of the rendered control into my dropdownlist's onchange event so I can guarantee the control Id on the client-side.  This is extremely important since this particular site uses a series of nested masterpages and you can never be too sure what the output control id will be.  I then wrote some utility JavaScript functions to set CSS display style to "none" or "" depending on the values selected.  I also use client-side JavaScript to enable / disable appropriate validators (which is pretty cool).

ValidatorEnable("validatorId", false); // disable
ValidatorEnable("validatorId", true); // enable

It may seem like a bit more work solving problems on the client-side, but in the end it definitely makes the user experience more fluid.

* I have found that VB can be quite pleasant when written correctly.  I am not the definitive authority on correct programming but I'm pretty sure immuting a string object while enumerating an ArrayList with a series of nested if statements and for loops is not the correct way to display SQL data in tabular form.  I also can't think of a good reason to have 400+ lines in Page_Load. These practices aren't language-specific and would probably piss me off in any .NET platform.

Thursday, February 14, 2008 7:17:59 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Thursday, February 07, 2008

In response to the previous postingJames Arendt has comment the final word:

static internal String AredntWay(String[] list)
{
   return(String.Join(',',list));
}

Thanks James Arendt!

{6230289B-5BEE-409e-932A-2F01FA407A92}

C# | Wayne
Thursday, February 07, 2008 2:21:47 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  | 

C# .NET 3.0 has anonymous types, since I am working on some legacy projects I have the experience of using anonymous types already in VBScript.  Remember classic ASP? Not having to Dim your variables, and being able to assign a variable to an int, then a string.  Has it been so long ago that you forgotten all the fun you have had with anonymous types in classic ASP?

I have a project that is classic ASP and SQL Server, if we change the SQL Server column (i.e. rename it or change the type) we have to scan the classic ASP (Find In Files) then make the changes to all inline SELECTS, UPDATES, and DELETES.

So then we got smart and changed to stored procedures, now if the type changes the stored procedures doesn't compile, easier to find places that need to be changed, however we had to adjust the classic ASP to handle the new type as an output -- really not a problem becuase all VBScript is anonymous types. 

So then we got really smart and used ASP.NET CLR 2.0, a class library to talk to our database, and SQL Server.  We generated the class library from CodeSmith using the database schema as a template for the library.  Now we are doing really good.  If the database type changes, the class library changes (we regenerate it), and any code behind that is calling the class library will break becuase of the type change.  Strongly typed language how nice.

Now we have LINQ -- back to anonymous types, we can jump on the bandwagen and rewrite all our code behind to call LINQ.  Now if we make a database change we are back to find In files.  Full circle to our VBScript days. Yippee.

{6230289B-5BEE-409e-932A-2F01FA407A92}

 

C# | Wayne
Thursday, February 07, 2008 1:46:36 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 

My virtual dev server was running out of hard drive space. Wayne’s preferred solution was a new and different dev server. I called him a few days ago about a build problem but I don’t remember what that was. He dinked with my solution. One of things he turned on was signing. I didn’t notice and at the time everything kept building. But I needed to move to the new server. The major apps were installed. I just needed to move all my VS projects, and whatever else I had on the old server. This part is the drudgery. Move everything and then see if it builds.

 

Well it built but I didn’t notice that my business object dll wasn’t getting moved up to the web site. So the ObjectDataSource wasn’t finding my new class methods for the business object. Of course, I didn’t figure that out immediately. I thought the docs for the ODS were just missing something. Wayne looked at the project and couldn’t figure out how to solve the problem immediately because of the type of project I had for the web server. He was used to dealing with Web Application projects that look and feel more like Windows application projects. I didn’t know that I had an old-style web project instead with the app_code directory.

 

In order to fix the problem, I tried to move the files of the project into a Web Application project. No nothing built. It started saying I needed signed dll’s for two specific 3rd party libraries (assembly generation failed ... does not have a strong name). I knew I didn’t so I waited until Wayne came home from Tamales class. He had set the signed setting in order to fix the original problem of getting the object into the GAC, however gave up when he realized I was referencing third party object that also needed signing. The business object built but the web application didn’t. The new project type didn’t know anything about app_code so those files were moved into a new Classes directory off the root of the web application project. The next project was that the .aspx files couldn’t find those classes so we had to put the classes into a namespace. This meant all code files regardless of type were now in the same name space for both the business object library and the web application project. Next problem was that the controls on the aspx.cs pages were undefined or some error like that. We had to “convert” the web project files so that the “.designer” page was behind as well. Then we changed each “.designer” code page to also be in the same name space as everything else. Once that happened, the whole solution built.

Thursday, February 07, 2008 8:55:46 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, February 06, 2008

I'm working on the infrastructure for a new web site. Lots of data layer so I can test. But I don't want to spend loads of time with the UI for insert/update/delete from an admin standpoint. Sure the UI for customers will get plenty of time but my own interface can be functional but not pretty. I already have robust classes for the data layer. Do I build my own pages with calls to the data layer in the code behind? I want to remove as much testable code from the UI (aspx and aspx.cs) as possible. So I'm going to try to use the GridView with a DataSourceObject. Make the GridView and ObjectDataSource do most of the work since they are far more tested than any UI code I could write.

That's my logic anyway.

 

.net | Dina
Wednesday, February 06, 2008 8:30:17 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Tuesday, February 05, 2008

I have a friend who is constantly saying he can write code much faster by configuring the various data controls with the SQL insert, select, update, and delete statements. I tried this. It is true the page was much faster built. A few clicks, a few typed attributes. However, and this is a big however, that style of coding makes several assumptions. Under each assumptions, I'll also list why I think a middle layer needs to exist between the GUI and the database. For those of you who are laughing that I even need to make this argument, beware what project you take over. Look at the code first.

you configured the controls correctly the first time

   In order for the process to truely be fast, you can only touch it once. With a code library, you can easily grow the middle layer to suit all your needs without having to retouch that page using a data control.

you don't have any need to use that code again in that web app, ever

   Whatever you write is what the user, admin, etc see - one interface only. I know this is bogus but it's the only thing that backs up a "much faster" arguement. With a code library, you can have as many views into the data as you need. But, yes, you do have to write that code.

you don't test your code beyond it's first unit test

   In order to test this type of code, it's either by hand or a high-end gui/web tester. With a code library, there are several tools to unit test including nUnit or it's new version xUnit. Once you have the unit test, you can run your tests against every build. The unit tests will find error before your customers do - which is so much nicer.

no one else will ever touch your code

   Few decent programmers would work this way. It says you are lazy and work alone.

those controls will never change or be removed

   In order to get the full benefit of time savings, it has to live for the life of the project. However, with the middle layer, the logic can live beyond that app to any other app or variant. Of course, you could totally munge the library into a piece of #$% but both approaches assume the design skills are solid.

 

.net | Dina
Tuesday, February 05, 2008 7:57:07 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, February 04, 2008

The one newsletter that arrives in my inbox that is bound to perk me up anytime is from http://www.sqlservercentral.com/. It is sort of an older style newsletter but the contents are great. The editorials (yes, there are editorials) are also great. The main articles might not be right for me at the time but then there is the question and the community-submitted help code as a featured script.

Monday, February 04, 2008 9:18:20 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 

In response to the previous posting. A few weeks ago, I would certainly have solved this the same way that you did in "OldSchool" with the exception of using IEnumerable<string>. Why limit your code to just string arrays? Now that we have LINQ, we can get pretty fancy! Technically one line within the method but I split it up to aid readability.

 

static void Main(string[] args)

{

    string[] names = new string[] { "Andy", "Marcy", "Cindy", "Jennifer", "Aaron" };

 

    Console.WriteLine(NewSchool(names));

}

 

static string NewSchool(IEnumerable<string> list)

{

    return list.Aggregate(new StringBuilder(),

        (sb, n) => sb.Length == 0 ? sb.Append(n) :

         sb.Append(",").Append(n),

        sb => sb.ToString());

}

 

And for even more fun, I built a simple test harness for each of these three methods. The test: 10000 itterations where I concatenate a string array that contains 8192 elements. Junior ran 36 minutes and 41.5 seconds*. OldSchool ran 8.453 seconds. NewSchool ran 9.484 seconds. NewSchool is likely slightly slower than OldSchool because of the use of the delegate. * I was only able to run 100 itterations on Junior which ran 22.015 seconds. I then extrapolated from there. The actual result would likely be even longer given its use of memory.

Andy | LINQ
Monday, February 04, 2008 1:23:04 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 

Creating a comma delimited string from an array came up yesterday, here is a couple of methods, one from our junior developer and one that I did.  I entitled mine old school, because of the C coding that shaped my programming.

static internal String Junior(String[] list)
{
    String output = String.Empty;

    foreach (String item in list)
    {
        output += item + ",";
    }

    output.TrimEnd(',');

    return (output);
}

static internal String OldSchool(String[] list)
{
    StringBuilder output = new StringBuilder();

    foreach (String item in list)
    {
        if (String.IsNullOrEmpty(item))
            continue;

        if (output.Length > 0)
            output.Append(",");

        output.Append(item);
    }

    return (output.ToString());
}

Which one do you like?

{6230289B-5BEE-409e-932A-2F01FA407A92}

 

 

C# | Wayne
Monday, February 04, 2008 10:21:22 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  | 
 Friday, February 01, 2008

This presentation was given by Brad Wilson and James Newkirk, Microsoft. I sat in on Brad's Pair Programming Agile presentation at the first Seattle Code camp which I enjoyed alot. The first code camp had more Agile presentations. Apparently Agile is no longer the shinny new toy because there was only one presentation on saturday in that area. James has been with xUnit, since some part of it's JUnit days, through NUnit and now the new version of XUnit. He went through the history which explained some of the wierdness the process has had. He also went through a discussion of what they were concerned about when they decided to build a new TDD framework. It was nice to hear real world examples of bad logic or implementation. My favorite they mentioned was using the framework for code coverage. Code coverage is the process make making sure every line of code is executed. The idea being that the more executed code that goes through testing, the fewer bugs the release product will have. These two said that blank tests or non-functional nUnit tests were created in some environments they saw just to reach code coverage percentage requirements. The only place I have ever seen code coverage as a metric for quality was microsoft while working as a tester on OLEDB.  They wrote issues on the board people wanted to cover and they covered all of them. Very impressive.

During the code samples and execution, it was obvious these two preferred TestDriven.Net over any other runner of the framework.

I had to feel for the guy that asked about UI testing. He obviously didn't know anything about TDD. In response, the discussion for UI testing covered watiN.

Other linkable names mentioned during the discussion:

MBUnit

CruiseControl

Windows Presentation Foundation

Jeremy Miller

 

 

 

 

.net | Dina
Friday, February 01, 2008 8:41:08 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  | 

I have several reasons not to use open source and I will be posting all in short order.  By open source, I mean a free assembly I can get on the web that includes the source, usually a development tool that is build by a group of people.

For some time I have been debating weather to use open source projects for my C# programming, or to buy professional components.  By debating, I mean thinking about, trying, and experimenting with both -- however now it is time to put my ideas to paper and share.  Disclaimer: in a year I might change my mind, or a posted comment might change my mind.  However here is one tought to chew on:

We reference assemblies so that we can gain functionality without having to code the funtionality ourselves.  Microsoft provides some great functionality in the CLR and it allows us to make significant gains in productivitiy by not making up write the stuff in the CLR.  However, if Microsoft is missing the functionality and it isn't specific to your vertical or product -- there is a tendency to get the functionality from the web as a open source project.  I tend to get the source, recompile it and make it a project within my solution, instead of using the assembly already compiled -- this can be a whole other discussion.  Ok, to recap: I reference an assembly from the Internet because I don't want to write the code myself.

However, it is my experience that the open source projects are very buggy, which leaves me fixing them to get them to work.  Which means I am coding in someone elses code just to get the thing to work correctly.  If I purchased a professional product, I could just write customer support, provide a reproduction, and get a fix.  Which leads me to reason #1: There is no support, I would rather buy (and I mean have my company buy) a $1000 per license product and get support for bugs then fix and worry about the open source.  

Just to drive the point home, even popular projects like ICSharpCode.SharpZLib have bugs, I just fixed three of them.  And, no I am not going to submit the changes to the open source project -- it takes to much time, they will not like my changes (since I patched it and didn't fix it like I would my own code), and usually those developers are hard to reach (hiding from doing customer service) and snobby (not SharpZLib in paricular just open source developer in genderal).

{6230289B-5BEE-409e-932A-2F01FA407A92} 

 

Friday, February 01, 2008 8:54:09 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  | 
 Thursday, January 31, 2008

This was Wayne Berry's presentation about real-world crypto coding for web sites. The presentation was identical to his asp.net user group presentation. He stayed calm with 15 minutes of Digipen equipment not working and two room switches. But it was a great presentation and the level of detail and code was just right. He said he will post the presentation here at some point.

.net | Dina
Thursday, January 31, 2008 1:08:13 PM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [0]  |