动态返回内部类

本文关键字:内部类 返回 动态 | 更新日期: 2023-09-27 18:19:59

在以下代码中。函数getInstance动态创建AaaBbbCcc的实例。但是,如何动态生成Union3<...>.Case2(Bbb)

Union3<Aaa, Bbb, Ccc> getInstance(int i)
{
    Type t = getType(i); // one of Aaa, Bbb, Ccc
    var instance = Activator.CreateInstance(t);
    // .... set property values
    return ???? // Union3<Aaa, Bbb, Ccc>.Case?(instance) // 1 to 3 to replace the "?"
}
public abstract class Union3<A, B, C>
{
    public abstract T Match<T>(Func<A, T> f, Func<B, T> g, Func<C, T> h);
    public sealed class Case1 : Union3<A, B, C>
    {
        public readonly A Item;
        public Case1(A item) : base() { this.Item = item; }
        public override T Match<T>(Func<A, T> f, Func<B, T> g, Func<C, T> h)
        {
            return f(Item);
        }
    }
    public sealed class Case2 : Union3<A, B, C>
    {
        public readonly B Item;
        public Case2(B item) { this.Item = item; }
        public override T Match<T>(Func<A, T> f, Func<B, T> g, Func<C, T> h)
        {
            return g(Item);
        }
    }
    public sealed class Case3 : Union3<A, B, C>
    {
        public readonly C Item;
        public Case3(C item) { this.Item = item; }
        public override T Match<T>(Func<A, T> f, Func<B, T> g, Func<C, T> h)
        {
            return h(Item);
        }
    }
}

动态返回内部类

动态创建泛型类型时,必须使用Type.MakeGenericType:

Union3<Aaa, Bbb, Ccc> getInstance<Aaa, Bbb, Ccc>(int i)
{
    Type t = typeof(Aaa); // implementation of getType(i) left out
    var instance = Activator.CreateInstance(t);
    Type unionType = typeof(Union3<,,>).MakeGenericType(typeof(Aaa), typeof(Bbb), typeof(Ccc));
    var nestedTypes = unionType.GetNestedTypes();
    object unionInstance = null;
    Type toCreate = null;
    if (t == typeof(Aaa))
        toCreate= nestedTypes.Single(x => x.Name == "Case1").MakeGenericType(typeof(Aaa), typeof(Bbb), typeof(Ccc));
    else if (t == typeof(Bbb))
        toCreate= nestedTypes.Single(x => x.Name == "Case2").MakeGenericType(typeof(Aaa), typeof(Bbb), typeof(Ccc));
    else if (t == typeof(Ccc))
        toCreate= nestedTypes.Single(x => x.Name == "Case3").MakeGenericType(typeof(Aaa), typeof(Bbb), typeof(Ccc));
    else
        throw new NotImplementedException();
    unionInstance = Activator.CreateInstance(toCreate, instance);
    return (Union3<Aaa, Bbb, Ccc>)unionInstance;
}

这样做的最终结果将是具有正确Item Type的3个内部类之一的实例。