Обычно по параметру (тип значения или ссылочный тип) и, во-вторых, по типу возвращаемого значения.
Если у вас есть сигнатура метода, такая как DateTime DateTime.AddDays(int days)
, вы получаете два намека на то, что метод не влияет на исходное время даты - во-первых, DateTime является типом значения, во-вторых, он возвращает DateTime. Типы значений, если они изменены в теле метода, будут иметь только свои изменения, примененные локально к копии в стеке. Если тип значения не возвращен, вызывающая сторона никогда не сможет наблюдать эти изменения. Эталонные типы, напротив, могут быть изменены в вызывающем методе и могут иметь изменения, наблюдаемые вызывающей стороной.
Точно так же, если у вас есть метод, такой как IOrderedEnumerable<T> OrderBy(IEnumerable<T> enumerable)
, несмотря на тот факт, что тип ввода является ссылочным типом (и может быть изменен), намек на то, что при возвращении нового типа оригинал останется неизменным.
Наконец, это может быть подтверждено тестированием. Как общий интерес, все методы расширения цепочки методов LINQ возвращают новый IEnumerable<T>
, ленивые вычисляются и не изменяют переданное содержимое IEnumerable<T>
, вместо этого применяя фильтр, который оценивается, когда вызывается GetEnumerator
возвращенный IEnumerable<T>.