public class A { public A(Control control) { //... } } public class B : A { public B(Control control) :base(control) { //... } } public class C : A { public C(Control control) :base(control) { //... } } public static class Factory { public static T Instantiate<T>(Control control) where T : A, new() { return new T(control); // Тут ошибка } } 

'T' cannot provide arguments when variable of a variable type

Through Ativator, they say, 11 times slower than through new T () Is there any way to pass the parameter to the universal constructor?

  • 3
    So what, what is 11 times slower? For you, in reality it is important, it will be 50 or 500 nanoseconds? - VladD
  • 2
    No, it’s impossible to simplify through the generalized type, since generalizations support only constructors without parameters. - rdorn
  • @VladD, generally speaking, I was just wondering if there was a faster way, because if there is one, why spend 55 nanoseconds if I can spend 5. In any case, I cannot transfer parameters for now, so I’ll look for another solution. - Bloodskys
  • @Bloodskys: Well, hm. If your code works with graphics, then there is a loss of 500 nanoseconds - it’s like a burnt match compared to launching a rocket into space. - VladD
  • one
    The obvious and natural option is Activator.CreateInstance . According to your words, you do not want to use it, because it "is said to be 11 times slower." This means that you are trying to optimize. At least, it seemed to me from your words. - VladD

1 answer 1

 public static class Factory { private static readonly Dictionary<Type, Func<Control, A>> _typeToActivator = new Dictionary<Type, Func<Control, A>> { [typeof(A)] = (c) => new A(c), [typeof(B)] = (c) => new B(c), [typeof(C)] = (c) => new C(c), }; public static T Instantiate<T>(Control control) where T : A { return (T)_typeToActivator[typeof(T)](control); } } 

If you do not want to fill the _typeToActivator dictionary manually, you can using the following method:

 private static Func<Control, T> CreateActivator<T>() where T:A { var ctor = typeof(T).GetConstructor(new Type[] {typeof(Control)}); var prm = Expression.Parameter(typeof(Control)); return Expression.Lambda<Func<Control, T>>( Expression.New(ctor, prm), prm ).Compile(); } 

those. you can find all the classes derived from A, and having the desired constructor using Reflection, and fill in the dictionary.