C#: Generic types that have a constructor?

后端 未结 5 1376
一个人的身影
一个人的身影 2021-02-02 12:28

I have the following C# test code:

  class MyItem
  {
    MyItem( int a ) {}
  }

  class MyContainer< T >
    where T : MyItem, new()
  {
    public void          


        
5条回答
  •  旧巷少年郎
    2021-02-02 13:15

    IMO, the best approach here is an initialize method, i.e.

    interface ISomeInterface {
        void Init(int i);
    }
    class Foo : ISomeInterface {
        void ISomeInterface.Init(int i) { /* ... */ }
    }
    static class Program {
        static T Create(int i) where T : class, ISomeInterface, new() {
            T t = new T();
            t.Init(i);
            return t;
        }
        static void Main() {
            Foo foo = Create(123);
        }
    }
    

    However, you can do what you want with Expression (but without compile-time support):

    using System;
    using System.Linq.Expressions;
    class Foo {
        public Foo(int i) { /* ... */ }
    }
    static class Program {
        static T Create(int i) {
            return CtorCache.Create(i);
        }
        static class CtorCache {
            static Func ctor;
            public static T Create(int i) {
                if (ctor == null) ctor = CreateCtor();
                return ctor(i);
            }
            static Func CreateCtor() {
                var param = Expression.Parameter(typeof(int), "i");
                var ci = typeof(T).GetConstructor(new[] {typeof(int)});
                if(ci == null) throw new InvalidOperationException("No such ctor");
                var body = Expression.New(ci, param);
                return Expression.Lambda>(body, param).Compile();
            }
        }
        static void Main() {
            Foo foo = Create(123);
        }
    }
    

    Note that this caches and reuses the delegate for performance.

提交回复
热议问题