C# – Switching on types

Many programming languages have it, and many people would like to see this in C#: the ability to do switch on types. While the following example is far fetched and shows bad programming practices, if it would ever be implemented, I’d expect it to look like this:

class A { string Name { get; } }
class B : A { string LongName { get; } }
class C : A { string FullName { get; } }
class X { public string ToString(IFormatProvider provider); }
class Y { public string GetIdentifier(); }

public string GetName(object value)
{
    switch typeof(value)
    {
        case C: return value.FullName;
        case B: return value.LongName;
        case A: return value.Name;
        case X: return value.ToString(CultureInfo.CurrentCulture);
        case Y: return value.GetIdentifier();
        default: return value.ToString();
    }
}

Notice how the case C and case B have to be specified before case A, as the code would match the first. This is against the definition of switch in C#, which states that the order of the cases does not matter. A generalization of this concept and its problems are discussed in this rather old MSDN blog post by Peter Hallam.


However, it is likely that you’d want to use just such a type switching construct in your code. Instead of writing a whole string of if-statements, you can do this by using this static class I wrote:

public static class TypeSwitch
{
    public static Switch<TSource> On<TSource>(TSource value)
    {
        return new Switch<TSource>(value);
    }

    public class Switch<TSource>
    {
        private TSource value;
        private bool handled = false;

        internal Switch(TSource value)
        {
            this.value = value;
        }

        public Switch<TSource> Case<TTarget>(Action<TTarget> action)
            where TTarget : TSource
        {
            if (!handled)
            {
                var sourceType = value.GetType();
                var targetType = typeof(TTarget);
                if (targetType.IsAssignableFrom(sourceType))
                {
                    action((TTarget)value);
                    handled = true;
                }
            }

            return this;
        }

        public void Default(Action<TSource> action)
        {
            if (!handled)
                action(value);
        }
    }
}

Download the full, commented source

The example at the start of the post will be written like this:

public string GetName(object value)
{
    string name = null;
    TypeSwitch.On(operand)
        .Case((C x) => name = x.FullName)
        .Case((B x) => name = x.LongName)
        .Case((A x) => name = x.Name)
        .Case((X x) => name = x.ToString(CultureInfo.CurrentCulture))
        .Case((Y x) => name = x.GetIdentifier())
        .Default((x) => name = x.ToString());
    return name;
}
Posted in C# | Leave a comment

Solution: Windows Live Movie Maker will not export movie with .wmv video clip in it

The problem

Recently I had a problem with Windows Live Movie Maker on Windows 7 x64 where it would refuse to export a movie that had a .wmv video clip in it. I successfully exported that video clip from Movie Maker before, and it consisted of only .avi and .mod video clips. Using that clip in my new movie seemed to go all fine, but when trying to export it to a video file, I got the following errors:

Sorry, your movie can’t be saved. Find any missing files or remove the unusable items from your project, and then try again. Error: 0xC945002D

Do you want to remove ’028.AVI’ from the project? The file might be corrupted or in a format that Movie Maker doesn’t recognize. Error: 0xC945002D

The solution

I was not able to remove this error for now and ever. But I was able to get Windows Live Movie Maker to export my movie. This is how I did it:

  1. Download and install Freemake Video Converter. Be sure not to install any of the advertising toolbars and things.
  2. Convert the .wmv file that you want to use in your video to an .avi file, using this tool. The default settings worked just fine for me.
  3. Open your Movie Maker project file (the .wlmp file) with your favorite plain text editor (such as Notepad++).
  4. Look in the MediaItems section and replace the path pointing to the .wmv file with the new path of the .avi file.
  5. Save the file. Open it in Movie Maker and try exporting it again. It worked for me, without having to slice my clip again.

In my Movie Maker project file, the MediaItems section looked like this:

<MediaItems>
    <MediaItem id="1" filePath="C:\Clips\MyClip.wmv"
      arWidth="1920" arHeight="1080" duration="13.994" />
</MediaItems>

And after step 4, it looked like this:

<MediaItems>
    <MediaItem id="1" filePath="C:\Clips\MyClip.avi"
      arWidth="1920" arHeight="1080" duration="13.994" />
</MediaItems>

Good luck!

Posted in Solutions | 1 Comment