2014-08-28 57 views
0

在下面的代码中。功能getInstance动态创建Aaa,BbbCcc的实例。但是,如何动态生成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

'if(i == 1)return new Case1(instance)'etc ...?不确定你在问什么,因为你不能返回一个新的'Union3 ',因为它的摘要 – 2014-08-28 22:10:14

回答

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; 
} 

这样做的最终结果将是3个内部类的一个实例与正确的ItemType