Как уже отмечалось, проблема в том, что типы делегатов не являются «структурными». То есть, они не имеют эквивалентности, основанной на их «структуре».
Теперь это, возможно, хорошая вещь для некоторых типов.Если у вас есть
struct MyRectangle { int x; int y; int width; int height; ... }
и
struct YourRectangle { int x1; int y1; int x2; int y2; ... }
, очевидно, было бы ошибкой позволить экземпляры MyRectangle быть отнесены к переменным YourRectangle, только потому, что они оба состояли из четырех Интс. Сеантика разных типов различна, поэтому типы не эквивалентны.
То же самое, теоретически, верно для делегатов. У вас может быть
delegate int Pure(string x);
delegate int Func(string x);
, где «чистая» функция не имеет побочных эффектов, и один и тот же выход с одним и тем же входом. Поскольку каждый Pure логически является Func, но каждый Func не обязательно является Pure, между ними не должно быть структурного набора.
На практике, конечно, система типов не очень хорошо поддерживает такие понятия, как «чистая функция». И на практике подавляющее большинство попыток конвертировать между типами делегатов совершенно безопасны: преобразование из Func<int, bool>
в Predicate<int>
и так далее.
Итак, две вещи, одна смотрит назад и одна смотрит вперед. Назад: если бы нам пришлось повторять это снова, я думаю, что делегаты, вероятно, были бы структурно напечатаны в CLI. Вы не всегда знаете, какие функции будут полезны при разработке новой структуры, а неструктурные типы делегатов до сих пор оказались не такими полезными, как, возможно, ожидалось. Нападающие: я ожидаю увидеть больше возможностей в будущих версиях CLR, которые позволят более структурировать типизацию. Например, функция «no pia» в C# 4 состоит в том, чтобы создать два типа, которые семантически и структурно одинаковы, но определенные в разных сборках, логически унифицировать структурно.
Похоже Theres неявное приведение от делегата к действию, но не наоборот. Вы можете попытаться сделать это, или вы можете просто изменить 't = новый поток (doIt);' to 't = new Thread (doIt.Invoke);' для тех же результатов. –