Чтобы ответить на одну часть вашего вопроса:
return new Concrete1() as T; // type T cannot be used with the as
Тип T
нельзя использовать с as
, поскольку T
не известен как ссылочный тип. Вы можете ограничить класс ссылочным типом с помощью ограничения where T : class [, ...]
. Это позволит вам использовать оператор as
, если, конечно, вам не нужно будет использовать этот метод с типами значений.
EDIT
Сказав это, я предпочитаю ответ Рсенны. Поскольку во время компиляции вы знаете, что прямое приведение будет работать, более разумно использовать прямое приведение, чем as
. . Я также согласен с его рекомендацией исследовать «реальные» контейнеры IoC, но я бы добавил, что глубокое понимание дженериков будет очень полезно для вас, когда вы узнаете о них. Поскольку вы говорите, что вы новичок в дженериках, подобное упражнение, вероятно, является хорошей идеей , потому что оно поможет вам узнать об дженериках и даст вам лучшее понимание ценности, которую могут использовать контейнеры IoC. добавить.
РЕДАКТИРОВАТЬ 2
Я вижу еще одну проблему: вы ограничиваете T как InterfaceBase, а затем приводите Concrete1 к T. Не известно, что Concrete1 является производным от T! Именно поэтому вы используете as
приведение. Ответ таков: добавьте ограничение class
, и все будет в порядке.
РЕДАКТИРОВАТЬ 3
Как указывает rsenna, вы также можете получить проверку типа во время выполнения с upcast и downcast:
return (T)(object)new Concrete1();
или
return (T)(InterfaceBase)new Concrete1();
Интересно, как это сравнить с точки зрения эффективности с
return new Concrete1() as T;
Я проверю позже сегодня, найду ли я для этого время.