variantの正体

C#enumに似たようなものらしいのですが、イマイチつかめていないのでちょっと弄ってみました。

using System.Console;

variant Color {
  | Red
  | Green
  | Blue
  | Different {
    red : int;
    green : int;
    blue : int;
  }
}

class Program {
  static Print (colors : array[Color]) : void {
    for (mutable i = 0; i < colors.Length; ++i) {
      match (colors[i]) {
        | Color.Red => WriteLine("Red")
        | Color.Green => WriteLine("Green")
        | Color.Blue => WriteLine("Blue")
        | Color.Different (r, g, b) => WriteLine("({0},{1},{2})", r, g, b);
      }
    }
  }

  static Main() : void {
    def arr = array (4);
    arr[0] = Color.Red();
    arr[1] = Color.Green();
    arr[2] = Color.Blue();
    arr[3] = Color.Different(0, 127, 255);

    Print(arr);
  }
}
/* 
Red
Green
Blue
(0,127,255)
 */

enumっぽいですが、Color.Differentで独自のデータを持っているところが特徴的ですね。分かったよーで分からないvariantですが、reflectorで逆コンパイルしてみると、

internal abstract class Color
{
      // Methods
      protected Color();
      public abstract override int _N_GetVariantCode();

      // Nested Types
      internal protected sealed class Blue : Color
      {
            // Methods
            static Blue();
            private Blue();
            public static Color.Blue _N_constant_object_generator();
            public override int _N_GetVariantCode();

            // Fields
            public static Color.Blue _N_constant_object;
      }

      internal protected sealed class Different : Color
      {
            // Methods
            public Different(int red, int green, int blue);
            public override int _N_GetVariantCode();

            // Fields
            public int blue;
            public int green;
            public int red;
      }

      internal protected sealed class Green : Color
      {
            // Methods
            static Green();
            private Green();
            public static Color.Green _N_constant_object_generator();
            public override int _N_GetVariantCode();

            // Fields
            public static Color.Green _N_constant_object;
      }

      internal protected sealed class Red : Color
      {
            // Methods
            static Red();
            private Red();
            public static Color.Red _N_constant_object_generator();
            public override int _N_GetVariantCode();

            // Fields
            public static Color.Red _N_constant_object;
      }
}

奇妙なネストクラスでした。