Advertisement
Guest User

ConstantTaggedUnion

a guest
Nov 4th, 2014
615
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 1.89 KB | None | 0 0
  1. using System;
  2. using System.Diagnostics;
  3. using System.Runtime.InteropServices;
  4.  
  5. using CT1 = Int32;
  6. using CT2 = System.Collections.Generic.List<Int32>;
  7.  
  8. public struct ConstantTaggedUnion
  9. {
  10.     // System.TypeLoadException: Could not load type '_Union' because it contains an object field at offset 0 that is incorrectly aligned or overlapped by a non-object field.
  11.     public static void test()
  12.     {
  13.         ConstantTaggedUnion foo = 1;
  14.  
  15.         Debug.Assert(foo.GetUnionType() == typeof(int));
  16.         { int bar = (int) foo; }
  17.  
  18.         foo = new CT2();
  19.     }
  20.  
  21.     public ConstantTaggedUnion(CT1 value) { _union=new _Union{Type1=value}; _id=1; }
  22.     public ConstantTaggedUnion(CT2 value) { _union=new _Union{Type2=value}; _id=2; }
  23.  
  24.     public CT1 Type1 { get{ if(_id!=1)_TypeError(1); return _union.Type1; } set{ _union.Type1=value; _id=1; } }
  25.     public CT2 Type2 { get{ if(_id!=2)_TypeError(2); return _union.Type2; } set{ _union.Type2=value; _id=2; } }
  26.  
  27.     public static explicit operator CT1(ConstantTaggedUnion value) { return value.Type1; }
  28.     public static explicit operator CT2(ConstantTaggedUnion value) { return value.Type2; }
  29.     public static implicit operator ConstantTaggedUnion(CT1 value) { return new ConstantTaggedUnion(value); }
  30.     public static implicit operator ConstantTaggedUnion(CT2 value) { return new ConstantTaggedUnion(value); }
  31.  
  32.     public byte Tag {get{ return _id; }}
  33.  
  34.     public Type GetUnionType()
  35.     {switch(_id){
  36.         case 1:  return typeof(CT1);
  37.         case 2:  return typeof(CT2);
  38.         default: return typeof(void);
  39.     }}
  40.  
  41.     public override string ToString()
  42.     {switch(_id){
  43.         case 1:  return _union.Type1.ToString();
  44.         case 2:  return _union.Type2.ToString();
  45.         default: return "void";
  46.     }}
  47.  
  48.     _Union _union;
  49.     byte _id;
  50.     void _TypeError(byte id) { throw new InvalidCastException(/* todo */); }
  51.  
  52.     [StructLayout(LayoutKind.Explicit)]
  53.     struct _Union
  54.     {
  55.         [FieldOffset(0)] public CT1 Type1;
  56.         [FieldOffset(0)] public CT2 Type2;
  57.     }
  58. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement