Существует ли общий тип-ограничение для "где НЕ выводится из"?
Мы можем указать ограничение "производное от" на параметры типового типа, например:
class Bar<T> where T : IFooGenerator
Есть ли способ указать NOT, полученный из?
Мой прецедент: у меня есть связка FooGenerator
, которые являются параллелизуемыми, с одинаковым кодом распараллеливания для каждого, но мы не хотим, чтобы они всегда были распараллелены.
public class FooGenerator : IFooGenerator
{
public Foo GenerateFoo() { ... }
}
Таким образом, я создаю общий контейнерный класс для генерации Foo параллельно:
public class ParallelFooGenerator<T> : IFooGenerator where T : IFooGenerator
{
public Foo GenerateFoo()
{
//Call T.GenerateFoo() a bunch in parallel
}
}
Поскольку я хочу, чтобы FooGenerator
и ParallelFooGenerator<FooGenerator>
были взаимозаменяемыми, я делаю ParallelFooGenerator : IFooGenerator
. Тем не менее, я явно не хочу, чтобы ParallelFooGenerator<ParallelFooGenerator>
был законным.
Итак, как вспомогательный вопрос, может быть, лучший способ его разработки, если невозможны "не производные от" ограничений?
Ответы
Ответ 1
Вы можете использовать что-то вроде следующего:
public interface IFooGenerator
{
Foo GenerateFoo();
}
interface ISerialFooGenerator : IFooGenerator { }
interface IParallelFooGenerator : IFooGenerator { }
public class FooGenerator : ISerialFooGenerator
{
public Foo GenerateFoo()
{
//TODO
return null;
}
}
public class ParallelFooGenerator<T> : IParallelFooGenerator
where T : ISerialFooGenerator, new()
{
public Foo GenerateFoo()
{
//TODO
return null;
}
}
Ответ 2
ParallelFooGenerator<ParallelFooGenerator>
уже невозможно, потому что ParallelFooGenerator
- это общий тип, и вы не указали общий аргумент.
Например, ParallelFooGenerator<ParallelFooGenerator<SomeFooGenerator>>
возможен - и допустил бы такой тип действительно быть плохим?
Ответ 3
Простой ответ - нет.
Длинный ответ (все еще нет):
Microsoft хорошо описывает их объяснение ограничений типов: "У компилятора должна быть определенная гарантия того, что оператор или метод, который ему нужно вызвать будет поддерживаться любым аргументом типа, который может быть указан кодом клиента."
Основная цель ограничений заключается не в запрете использования определенных типов, а в том, чтобы позволить компилятору узнать, какие операторы или методы поддерживаются. Тем не менее, вы можете проверить, реализует ли тип/наследует определенный интерфейс/базовый класс во время выполнения и генерирует исключение. Тем не менее, вы не сможете получить ошибку времени разработки от intellisense.
Надеюсь, это поможет.