在以下代码中。函数getInstance
动态创建Aaa
,Bbb
和Ccc
的实例。但是,如何动态生成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);
}
}
}
答案 0 :(得分:0)
动态创建泛型类型时必须使用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个内部类之一的实例。