До .net нормальный шаблон был для TryXX
методов, которые просто оставляли переданный по ссылке аргумент неизмененным. Это был очень полезный шаблон, так как это означало, что код, который хотел использовать значение по умолчанию, мог сделать что-то вроде:
MyNum = 5;
TryParsing(myString, &myNum);
в то время как код, который не хочет использовать значение по умолчанию, может использовать:
if (TryParsing(myString, &myNum))
{ .. code that uses myNum .. }
else
{ .. code that doesn't use myNum .. }
В первом случае вызывающий код должен был бы обеспечить инициализацию myNum
перед вызовом, но не беспокоиться о возвращаемом значении TryParsing
. При последнем использовании вызывающему коду придется беспокоиться о возвращаемом значении, но не нужно инициализировать myNum
перед вызовом. Сама подпрограмма TryParsing
не должна беспокоиться о том, какое использование было предназначено.
Однако
C # не очень хорошо допускает такой шаблон, если только TryParsing
не написан на другом языке. Либо TryParsing
должен быть записан таким образом, чтобы предыдущее значение myNum
было безусловно перезаписано без проверки, вызывающий должен безоговорочно инициализировать его, либо для двух сценариев должны быть предусмотрены разные методы. Если бы метод TryParsing
был написан на каком-то другом языке, он теоретически мог бы вести себя как методы старого стиля (записать аргумент в случае успеха и оставить его в покое, если нет), при этом все еще называя его параметром out
. Однако я не рекомендовал бы это, потому что причудливое поведение не ограничивалось бы этим out
параметром.
Предположим, например, что метод этого стиля использует аргумент типа fooStruct
, а fooStruct
имеет конструктор, который выглядит следующим образом:
fooStruct(string st)
{
fooStruct.TryParse(st, out this);
}
Компилятор был бы совершенно доволен таким конструктором, поскольку он "определенно" пишет this
. С другой стороны, если какой-то другой код делает:
while(someCondition)
{
var s = new fooStruct(someString);
...
}
Можно ожидать, что s
будет содержать инициализированную структуру (если someString
допустимо) или будет пустым (если это не так). Ничто в этом коде не предполагает, что s
может сохранять свое значение между повторениями цикла. Тем не менее, это именно то, что могло бы произойти.