代码之家  ›  专栏  ›  技术社区  ›  David Neale

使用内部构造函数创建泛型类

  •  2
  • David Neale  · 技术社区  · 14 年前

    是否可以在泛型方法中使用内部构造函数构造对象?

    public abstract class FooBase { }
    
    public class Foo : FooBase {
       internal Foo() { }
    }
    
    public static class FooFactory {
        public static TFooResult CreateFoo<TFooResult>()
        where TFooResult : FooBase, new() {
            return new TFooResult();
        }
    }
    

    FooFactory 与驻留在同一程序集中 Foo . 类调用工厂方法的方式如下:

    var foo = FooFactory.CreateFoo<Foo>();
    

    它们得到编译时错误:

    有什么办法可以解决这个问题吗?

    Activator.CreateInstance<TFooResult>(); 
    

    这会在运行时引发相同的错误。

    4 回复  |  直到 14 年前
        1
  •  5
  •   Ani    14 年前

    你可以移除 new() 约束和返回:

    //uses overload with non-public set to true
    (TFooResult) Activator.CreateInstance(typeof(TFooResult), true); 
    

    尽管客户也可以这么做。但是,这很容易出现运行时错误。

    这是一个很难以安全的方式解决的问题,因为该语言不允许抽象构造函数声明。

        2
  •  0
  •   Kikaimaru    14 年前

    公众的 约束,new()约束必须

    http://msdn.microsoft.com/en-us/library/d5x73970.aspx

    edit:所以不,如果使用new()约束,就不能传递该类,如果不使用new()约束,就可以尝试使用反射来创建新实例

    public static TFooResult CreateFoo<TFooResult>()
    where TFooResult : FooBase//, new()
            {
                return (TFooResult)typeof(TFooResult).GetConstructor(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance, null, new Type[] {}, null).Invoke(new object[]{});
                //return new TFooResult();
            }
    
        3
  •  0
  •   VinayC    14 年前

    可以有一些工作,如下文,但我不认为你想去的方式!

    • 将创建基于实例的 类型参数的类型。

    • 除了类型参数和具体实现之间的映射之外,在类似的行上扩展将是外部代码(xml文件、配置等)。IOC/DI容器也可以在这里提供帮助。

        4
  •  0
  •   Tawani    13 年前
    public class GenericFactory
    {
        public static T Create<T>(object[] args)
        {
            var types = new Type[args.Length];
            for (var i = 0; i < args.Length; i++)
                types[i] = args[i].GetType();
    
            return (T)typeof(T).GetConstructor(types).Invoke(args);
        }
    }