Можно ли ограничить конструкторы классов, реализующих интерфейс? - PullRequest
1 голос
/ 16 февраля 2012

Можно ли установить ограничение, которое должно быть у всех классов, реализующих интерфейс, например, пустой конструктор?Как и ограничение where T : new() в общем?

Ответы [ 6 ]

5 голосов
/ 16 февраля 2012

Нет - невозможно наложить какие-либо подобные ограничения на производные классы или разработчики данного интерфейса.

Такие ограничения обычно не будут особенно хорошей идеей / полезностью в любом случае, так как обычно при работе с интерфейсом вы обычно работаете с экземплярами объектов, которые реализуют этот интерфейс, и в этом случае объект, естественно, уже создан и такие ограничения избыточны. (Конечно, исключение составляют дженерики, в этом случае вы можете использовать ограничение new()).

Я предполагаю, что вы пытаетесь создать какую-то систему плагинов и хотите ограничить реализацию интерфейса вашего плагина, чтобы иметь конструктор по умолчанию, который вы можете использовать для создания экземпляров ... если это так, то обычно лучше альтернативы, которые вы можете использовать, такие как MEF .

Не могли бы вы подробнее рассказать, зачем вам это нужно?

1 голос
/ 17 февраля 2012

Есть только четыре способа, которыми я могу думать, что вам могут дать класс во время выполнения, который не известен во время компиляции. Вам может быть предоставлен экземпляр объекта, который реализует интерфейс, и вы хотите создать другой объект, подобный этому. Этот сценарий лучше всего обработать, включив в интерфейс метод NewSimilarInstance(). У вас может быть метод в каком-то классе, который получает параметр общего типа, который ограничен вашим интерфейсом. В этом сценарии подпрограмма, которая принимает универсальный параметр, может иметь ограничение new(). В противном случае вам может быть предоставлен объект .net System.Type или какое-либо другое представление (например, строка) для типа. В этих последних двух сценариях никакая проверка во время компиляции не будет иметь смысла; для выполнения каких-либо действий с типами потребуется Reflection, поэтому вы также можете использовать Reflection, чтобы увидеть, позволяют ли они создавать новые экземпляры.

1 голос
/ 16 февраля 2012

Нет, ничего подобного. Было бы немного странно, учитывая, что обычное использование интерфейсов состоит в том, что код, использующий интерфейс, не должен заботиться о том, как он был создан - им не нужно заботиться о том, что такое класс реализации, просто о том, что он реализует интерфейс .

Если у вас есть для этого какое-то специальное применение, я предлагаю вам просто написать для него модульные тесты - если все реализации будут в одной сборке, это будет довольно просто сделать, и все ошибки будут обнаружены в * 1003. * почти в то же время, что и во время компиляции ...

0 голосов
/ 16 февраля 2012

Внедрите Factory в ваш универсальный класс, который может создать экземпляр вашего интерфейса, и отбросьте ограничение new ().

Что-то вроде:

public interface IFactory<out T>
{
    T CreateInstance();
}

public class GenericClass<T>
{
     private readonly IFactory<T> _factory;

     public GenericClass(IFactory<T> factory)
     {
          _factory = factory;
     }

     public DoSomething()
     {
          //...
          T foo = _factory.CreateInstance();
          //...
     }
}
0 голосов
/ 16 февраля 2012

Как сказал Джастин, вы не только не можете ограничить сигнатуры конструктора с помощью интерфейса, но также невозможно использовать абстрактный класс.Возможно, если бы вы объяснили, почему вам нужно поместить такое ограничение, мы могли бы найти другие решения для вашей проблемы

0 голосов
/ 16 февраля 2012

Я думаю, вам нужно использовать виртуальный класс для этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...