Единственное объяснение, которое я могу придумать, это то, что компилятор достаточно умен, чтобы понять, что существует неявный оператор, который преобразует длинный в десятичный, который он может использовать для удовлетворения явного преобразования между Программой и десятичным, когда Программа может преобразовать только в длинный.
6.1.2 Неявные числовые преобразования
Неявные числовые преобразования:
· От sbyte до short, int, long, float, double или decimal.
· От байта к короткому, ushort, int, uint, long, ulong, float,
двойной или десятичный.
· От короткого до целого, длинного, плавающего, двойного или десятичного.
· От ushort к int, uint, long, ulong, float, double или
десятичное.
· От int до long, число с плавающей запятой, двойное число или десятичное число.
· От мятных до длинных, удлиненных, плавающих, двойных или десятичных.
· От длинных до плавающих, двойных или десятичных.
· От ulong до float, double или decimal.
· От символа к ushort, int, uint, long, ulong, float, double,
или десятичный.
· От поплавка к удвоению.
Преобразования из int, uint, long или ulong в float и из long или
Удвоение может привести к потере точности, но никогда не приведет к
потеря величины. Другие неявные числовые преобразования никогда не теряют
любая информация.
Нет неявных преобразований в тип char, поэтому значения
другие целочисленные типы не преобразуются автоматически в тип char.
Таким образом, при преобразовании между Программой и десятичным знаком C # знает, что он может неявно преобразовывать любой числовой тип в десятичный, поэтому при выполнении этого явного преобразования он ищет любой оператор, который может преобразовать Программу в числовой тип.
Что было бы интересно посмотреть, что произойдет, если вы также добавите явное преобразование, скажем, в uint, которое вернуло 48? Какой из них выберет компилятор?