Что касается статических методов, используемых в неуниверсальных контекстах, я согласен с тем, что не имеет смысла разрешать их в интерфейсах, поскольку вы не сможете вызывать их, если у вас все равно есть ссылка на интерфейс. Однако есть фундаментальная дыра в дизайне языка, созданная с использованием интерфейсов НЕ в полиморфном контексте, а в общем. В этом случае интерфейс вообще не интерфейс, а скорее ограничение. Поскольку в C # отсутствует концепция ограничения вне интерфейса, в нем отсутствует существенная функциональность. Показательный пример:
T SumElements<T>(T initVal, T[] values)
{
foreach (var v in values)
{
initVal += v;
}
}
Здесь нет полиморфизма, универсальный использует фактический тип объекта и вызывает оператор + =, но это не удается, так как он не может точно сказать, что этот оператор существует. Простое решение состоит в том, чтобы указать его в ограничении; простое решение невозможно, потому что операторы являются статическими, а статические методы не могут быть в интерфейсе, и (в этом проблема) ограничения представляются в виде интерфейсов.
То, что нужно C #, - это реальный тип ограничений, все интерфейсы также будут ограничениями, но не все ограничения будут интерфейсами, тогда вы могли бы сделать это:
constraint CHasPlusEquals
{
static CHasPlusEquals operator + (CHasPlusEquals a, CHasPlusEquals b);
}
T SumElements<T>(T initVal, T[] values) where T : CHasPlusEquals
{
foreach (var v in values)
{
initVal += v;
}
}
Уже много говорилось о создании IArithmetic для всех реализуемых числовых типов, но существует обеспокоенность по поводу эффективности, поскольку ограничение не является полиморфной конструкцией, поэтому ограничение CArithmetic решило бы эту проблему.