Рассмотрим следующий код в библиотеке классов:
public class Service
{
public delegate string Formatter(string s1, string s2);
public void Print(Formatter f)
{
Console.WriteLine(f("a", "b"));
}
}
И вот консольное приложение, которое его использует:
static void Main(string[] args)
{
s = new Service();
s.Print(Concat);
}
static string Concat(string s1, string s2)
{
return string.Format("{0}-{1}", s1, s2);
}
Пока он печатает "a-b", как и следовало ожидать.
Теперь я меняю библиотеку классов следующим образом:
public class Service
{
public delegate string Formatter(string s1);
public void Print(Formatter f)
{
Console.WriteLine(f("a"));
}
}
т.е. Я удалил один параметр из делегата. Я компилирую только библиотеку классов и перезаписываю dll, сидящую рядом с консольным приложением (консольное приложение не перекомпилировано). Я бы ожидал, что это нарушение в библиотеке, и если я запустил приложение, он обнаружит несоответствие, в результате чего возникнет какое-то исключение во время выполнения.
В отличие от этого, когда я запускаю приложение, здесь нет никакого исключения, и я получаю потрясающий вывод "-a". Когда я отлаживаю, я вижу, что вызывается метод Concat (с двумя параметрами), уровень стека вызовов ниже показывает вызов печати в f ( "a" ) (один параметр), без каких-либо ошибок. Самое интересное, что в Concat s1 имеет значение null, s2 является "a".
Я также играл с различными изменениями в сигнатуре (добавление параметров, изменение типа параметра) в основном с тем же результатом. Когда я изменил тип s2 из строки в int, я получил исключение, но не тогда, когда был вызван метод Concat, но когда он попытался вызвать string.Format.
Я попробовал это с .NET target framework 4.5.1 и 3.5, x86 и x64.
Может ли кто-нибудь ответить, является ли это ожидаемым поведением или ошибкой? Мне кажется довольно опасным.