Это отчасти связано с тем, что PropertyInfo.SetValue предшествует обобщению - отражение было частью .NET с самого начала.
Однако использование дженериков в данном конкретном случае будет затруднено любым способом. Как вы предположили, компилятор не может получить эту информацию, поскольку информация о свойствах получается во время выполнения, а не во время компиляции. В этом и состоит цель Reflection.
Вместо того, чтобы пытаться превратить это в универсальный метод (который, возможно, в любом случае должен был бы привести к неуниверсальной реализации из-за поведения во время выполнения), команда CLR позаботилась о том, чтобы все объекты, включая типы значений , работать как System.Object. Да, это вызывает бокс, но с учетом издержек отражения небольшие дополнительные издержки бокса с типом значения не вызывают особого беспокойства.