Важно, чтобы метод Main
помещался в класс, который правильно настроен в Visual Studio в качестве объекта запуска:
SimpleAIMLEditor.Program
в раскрывающемся списке для запуска object Теперь запустите приложение снова. Ошибка исчезнет.
Я использую вторую SUBSTRING, потому что она более портативна. Не во всех dbms было ВЛЕВО и ПРАВО.
t, производные от [или являются] Bar
T
s в Bar
или типы, производные от Bar
внутри тела Bar
на T
Тот факт, что класс Bar
определяет конструктор без параметров, не означает, что все, что является Bar
, будет делать это - может быть классом, унаследованным от Bar
, но скрывающим конструктор без параметров. Такой класс соответствовал бы ограничению Bar
, но не соответствовал бы ограничению new ()
.
(Обратите внимание, что если вы сделаете Bar
запечатанным
, чтобы избегайте этой возможности, вы можете (по понятным причинам) больше не использовать его в качестве общего ограничения) - edit попытка этого вызовет ошибку компилятора CS0701.
Возможно, потому что, если вы не включите ограничение new ()
, тогда T
на законных основаниях может быть подклассом Bar
без конструктора по умолчанию (т. е. общедоступного и без параметров), и в этом случае оператор new T ()
внутри метода будет недопустимым.
Bar
в качестве ограничения, T
может быть Bar
или любой производной от Bar
, с конструктором по умолчанию или без него. new ()
как ограничение, T
может быть любого типа с конструктором по умолчанию. Bar
и new ()
в качестве ограничений, T
должен быть Bar
или подклассом Bar
, а также должен иметь конструктор по умолчанию.Поскольку подклассы Bar могут не иметь конструктора без аргументов.
where T : Bar
указывает Bar или подкласс Bar. Если бы вам просто нужен был экземпляр Bar, вы бы не использовали дженерики. Существует множество экземпляров (например, Object и String), в которых суперкласс имеет конструктор без аргументов, а подкласс - нет.
Хотя Bar
может быть конкретным, производный класс T
может сам по себе является абстрактным или не имеет конструктора по умолчанию.
Вы, вероятно, могли бы использовать конструктор Bar:
T _t = new Bar();
без ограничения new ()
. Однако вы использовали конструктор T
, а компилятор не может и не предполагает, что создание типа, который привязывается к T, возможно, пока вы не добавите ограничение new ().
Для тех, кто не уверен, помните, что вы можете использовать
where T : IDeviceCommand
, чтобы потребовать, чтобы T реализовал некоторый интерфейс в качестве минимального контрактного требования. Вы могли бы выразить вышесказанное как «Вы можете позвонить мне, если предоставленный Тип 'T' как минимум реализует интерфейс IDeviceCommand». Это, конечно, позволяет вам сделать серию (правильных) предположений о том, какие средства «T» предоставляет вашему методу для работы.