Multiple Views (redux) 0

Jeremy posted an article on retrieving filtered results on collections, using the perennial Animal kingdom example. Great post.

As I was looking at this again, it just started looking “smelly”. First thought, can we do this cleaner with Generics?

public IEnumerable AnimalsList() where AnimalType:class
{
  foreach (IAnimal animal in _animals)
  {
    AnimalType testAnimal = animal as AnimalType;
    if (testAnimal != null)
      yield return testAnimal;
  }
}

Oh yeah… generics are just the coolest thing.

But, this still smelled to me (I didn’t like all the filter code inside the function). Sprinkling some functional programming goodness (thank you Dustin), it turned into this.

public delegate bool FilterAnimalPredicate(System.Type type);

/// snip

public IEnumerable AnimalList(FilterAnimalPredicate filter)
{
  foreach (IAnimal animal in _animals)
  {
    if (filter(animal.GetType()))
    {
      yield return animal;
    }
  }
}

Admittedly, I have cheated … we are no longer using a Property, and hence the unit tests had to change. But I’d take this approach as it feels much cleaner.

Thanks again to Jeremy for sparking this post.

Here’s the final Test Code:

using System;
using System.Collections;
using System.Collections.Generic;
using MbUnit.Framework;

namespace MultipleIterators.Test
{
    [TestFixture]
    public class ZooTest
    {

        private static bool IsElephant(System.Type type)
        {
            return (type is Elephant);
        }

        private static bool IsZebra(System.Type type)
        {
            return (type is Zebra);
        }

        [Test]
        public void Can_add_elephants_to_the_zoo()
        {
            Zoo zoo = new Zoo();
            zoo.AddAnimal(new Elephant());
            int animalCounter = 0;

            foreach (IAnimal animal in zoo.Animals){
                animalCounter++;
            }
            Assert.AreEqual(1, animalCounter);
        }

        [Test]
        public void Can_add_zebras_to_the_zoo()
        {
            Zoo zoo = new Zoo();
            zoo.AddAnimal(new Zebra());
            int animalCounter = 0;

            foreach (IAnimal animal in zoo.Animals){
                animalCounter++;
            }
            Assert.AreEqual(1, animalCounter);
        }

        [Test]
        public void Can_get_just_the_zebras_out_of_the_zoo()
        {
            Zoo zoo = new Zoo();
            zoo.AddAnimal(new Zebra());
            zoo.AddAnimal(new Elephant());

            foreach (Zebra zebra in zoo.AnimalsList<Zebra>()){
                Assert.IsTrue(zebra is Zebra);
            }
        }

        [Test]
        public void Can_get_just_the_elephants_out_of_the_zoo()
        {
            Zoo zoo = new Zoo();
            zoo.AddAnimal(new Zebra());
            zoo.AddAnimal(new Elephant());

            foreach (Elephant elephant in zoo.AnimalsList<Elephant>()){
                Assert.IsTrue(elephant is Elephant);
            }
        }

        [Test]
        public void Can_get_just_the_elephants_out_of_the_zoo_using_predicate()
        {
            Zoo zoo = new Zoo();
            zoo.AddAnimal(new Zebra());
            zoo.AddAnimal(new Elephant());

            foreach (Elephant elephant in zoo.AnimalList(IsElephant)){
                Assert.IsTrue(elephant is Elephant);
            }
        }
    }
}

Strict Types, good thing 1

Ok, so C# transformation of an existing VB.NET project isn’t quite as “smooth” as I would like, but it brings benefits of drilling in the whole “;” syntax.

Also what comes to a screaming head is the fact that in VB.NET you can get away with a lot under “normal” circumstances. You know, the one where you don’t declare “Option Strict On”. So porting to C#, the compiler conditionally complains of things like: Cannot implicitly convert type ‘int’ to ’string’

Currently, I’m telling it what to do:

foo.ToString();

Specifically telling computers what to do is an inherently good thing for programmers. Especially if you’re a control freak like me. Another “good thing” – touch-typing.

Further up, further in 0

So, having had worked at a great product development company for the past 4 1/2 years in VB6 and only getting to dabble in .NET when I could talk them into it, I’ve finally been blessed with a job that is aligned with my desires in .NET!

While I’ve built a handful of solutions, both webform and winform since 2001, they have all been in VB.NET. I’m going to try and push cold turkey and just switch to C#. Why?

Here’s what I can come up with:

  1. C# is “closer” to the .NET Framework – much of .NET framework was in C# and the whole experience is cleaner. I’m a control freak is the bottom line.
  2. C# is closer to Javascript – I’m planning on web programming, and jumping in and out of brackets and the like is just something I’m feeling too lazy for
  3. C# has huge momentum in the Software Engineering community – having MORE resources by industry experts, not just in the Microsoft camp is how I’d like to build software. Also, it seems that more open source projects run in the C# space than VB.NET (purely subjective).
  4. C# in Visual Studio 2k3 has better architect tools (i.e. code comments). Yes I know about the VB.NET add-in.
  5. Easier to share, debate – VB.NET still has a hobbyist aura. I’m anything but a hobbyist, but I grow tired of spending time on qualifications when discussing ideas.
  6. C# to VB.NET conversion is actually easier to me. Sure, I could read C# and convert to VB.NET. VB.NET does some things during compile time anyway that is more declarative (see #1) and I just don’t want any more tools that hide that stuff.
  7. Intellisense wins every time. Since I’m in Visual Studio .NET, it’s not like I’ll have “extra” typing to do.

Here we go!

I promise not to become a C# biggot.