Радиус «видимой» области на картах Google v3

Рассмотрим эту тривиальную функцию:

public static bool IsPositive(IComparable<int> value)
{
    return value.CompareTo(0) > 0;
}

Теперь, если я передам int этому методу, он будет упакован. Не лучше ли было бы поэтому определить вышеупомянутый метод следующим образом?

public static bool IsPositive<T>(T value) where T : IComparable<int>
{
    return value.CompareTo(0) > 0;
}

Используя общее ограничение таким образом, я могу достичь точно такой же функциональности, как и в приведенном выше коде, с дополнительным преимуществом, что бокс не требуется (так как вызов IsPositive принимает параметр типа int ).

Приведенный выше пример кода явно совершенно бессмыслен. Но мой более широкий вопрос: не будет ли всегда иметь смысл определять методы последним способом (с использованием общего ограничения, а не с параметром некоторого типа интерфейса), чтобы избежать потенциальной упаковки типов значений?

Я подозреваю, что ответ, скорее всего, будет «да», но это требует большего набора текста, и во многих случаях встреча с типом значения будет очень маловероятной, например, когда метод принимает некоторые IEnumerable «. Но мне интересно, есть ли большая разница между этими подходами, которые избегают меня в данный момент.

13
задан Dan Tao 19 August 2010 в 20:05
поделиться

3 ответа

Одна из проблем связана с тем, что общее ограничение на самом деле не является частью подписи. Если у вас есть ...

static T Method<T>(T value) where T : ICompareable<int>

... и ...

static T Method<T>(T value) where T : IEnumerable<int>

... у компилятора не будет способа узнать, кто из них кто.

И, ссылаясь на Эрика Липперта...

8
ответ дан 2 December 2019 в 00:17
поделиться

В комментарии к вопросу о том, вызывает ли вызов метода бокс после того, как передан аргумент.

Когда вы вызываете виртуальный метод для выражения, тип которого является параметром типа с ограничением на него, компилятор C # выдает инструкцию constrained.callvirt . Как можно было бы надеяться, это правильно; бокс случается только тогда, когда это абсолютно необходимо.

Подробнее о точной семантике упаковки ограниченных виртуальных вызовов см. В документации:

http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.constrained.aspx

7
ответ дан 2 December 2019 в 00:17
поделиться

Другая проблема может возникнуть, если универсальное ограничение относится к параметрам универсального типа параметризованного типа, например

static bool AreAllTheSame<T>(IEnumerable<T> something)
  where T : IEquatable<T>

. Не всегда возможно преобразовать параметр универсального типа таким образом, если вы не введете второй параметр типа вроде этого:

static bool AreAllTheSame<S, T>(S something)
  where S : IEnumerable<T>
  where T : IEquatable<T>

Это просто не выглядит правильным.

0
ответ дан 2 December 2019 в 00:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: