[Примечание: этот вопрос имел исходное название " объединение стилей C (ish) в С#" но, как сказал мне отчет Джеффа, видимо, эта структура называется "дискриминационным союзом".
Извините многословие этого вопроса.
Есть несколько аналогичных звуковых вопросов для моего уже в SO, но они, похоже, концентрируются на преимуществах экономии памяти в союзе или использовании их для взаимодействия. Вот пример такого вопроса.
Мое желание иметь тип типа объединения несколько отличается.
Я пишу код в данный момент, который генерирует объекты, которые немного похожи на это
public class ValueWrapper
{
    public DateTime ValueCreationDate;
    // ... other meta data about the value
    public object ValueA;
    public object ValueB;
}
Довольно сложный материал, я думаю, вы согласитесь. Дело в том, что ValueA может быть только нескольких определенных типов (скажем, string, int и Foo (который является классом), а ValueB может быть другим небольшим набором типов. t нравится рассматривать эти значения как объекты (я хочу, чтобы теплое плотное чувство кодирования с некоторой степенью безопасности).
Итак, я подумал о том, чтобы написать тривиальный маленький класс-оболочку, чтобы выразить тот факт, что ValueA логически является ссылкой на конкретный тип. Я назвал класс Union, потому что то, что я пытаюсь достичь, напомнило мне концепцию объединения в C.
public class Union<A, B, C>
{
    private readonly Type type; 
    public readonly A a;
    public readonly B b;
    public readonly C c;
    public A A{get {return a;}}
    public B B{get {return b;}}
    public C C{get {return c;}}
    public Union(A a)
    {
        type = typeof(A);
        this.a = a;
    }
    public Union(B b)
    {
        type = typeof(B);
        this.b = b;
    }
    public Union(C c)
    {
        type = typeof(C);
        this.c = c;
    }
    /// <summary>
    /// Returns true if the union contains a value of type T
    /// </summary>
    /// <remarks>The type of T must exactly match the type</remarks>
    public bool Is<T>()
    {
        return typeof(T) == type;
    }
    /// <summary>
    /// Returns the union value cast to the given type.
    /// </summary>
    /// <remarks>If the type of T does not exactly match either X or Y, then the value <c>default(T)</c> is returned.</remarks>
    public T As<T>()
    {
        if(Is<A>())
        {
            return (T)(object)a;    // Is this boxing and unboxing unavoidable if I want the union to hold value types and reference types? 
            //return (T)x;          // This will not compile: Error = "Cannot cast expression of type 'X' to 'T'."
        }
        if(Is<B>())
        {
            return (T)(object)b; 
        }
        if(Is<C>())
        {
            return (T)(object)c; 
        }
        return default(T);
    }
}
Использование этого класса ValueWrapper теперь выглядит следующим образом
public class ValueWrapper2
{
    public DateTime ValueCreationDate;
    public  Union<int, string, Foo> ValueA;
    public  Union<double, Bar, Foo> ValueB;
}
что-то вроде того, чего я хотел достичь, но у меня отсутствует один довольно важный элемент - это проверка принудительного типа компилятора при вызове функций Is и As, как показано в следующем коде
    public void DoSomething()
    {
        if(ValueA.Is<string>())
        {
            var s = ValueA.As<string>();
            // .... do somethng
        }
        if(ValueA.Is<char>()) // I would really like this to be a compile error
        {
            char c = ValueA.As<char>();
        }
    }
IMO Недействительно задавать ValueA, если это char, так как в его определении явно сказано, что это не так - это ошибка программирования, и я хотел бы, чтобы компилятор подхватил это. [И если я смогу получить это правильно, то (надеюсь), я тоже получу intellisense - что было бы благом.]
Чтобы достичь этого, я хотел бы сказать компилятору, что тип T может быть одним из A, B или C
    public bool Is<T>() where T : A 
                           or T : B // Yes I know this is not legal!
                           or T : C 
    {
        return typeof(T) == type;
    } 
Кто-нибудь знает, возможно ли то, что я хочу достичь? Или я просто глупый для написания этого класса в первую очередь?
Спасибо заранее.