Вспоминается шутка: начинающий программист думает что в килобайте тысяча байт, а опытный - что в километре - 1024 метра.
Так как сам немало читаю книг, в которых пишется как "должно быть", тем интереснее бывает, когда натыкаюсь на явные отклонения от этого самого "должно ...".
Детальный взгляд на код .NET Framework (не без помощи .NET Reflector) показывает, что не всё в работающих проектах бывает так, как начинающие думают.
Приведу такой пример.
Структура System.Char.Метод, проверяющий, является ли символ строки на указанной позиции числом.
public static bool IsNumber(string s, int index) { if (s == null) { throw new ArgumentNullException("s"); } if (index >= s.Length) { throw new ArgumentOutOfRangeException("index"); } char ch = s[index]; if (!IsLatin1(ch)) { return CheckNumber(CharUnicodeInfo.GetUnicodeCategory(s, index)); } if (!IsAscii(ch)) { return CheckNumber(GetLatin1UnicodeCategory(ch)); } return ((ch >= '0') && (ch <= '9')); }
Аналогичный ему метод, проверяющий, является ли числом один символ.
public static bool IsNumber(char c) { if (!IsLatin1(c)) { return CheckNumber(CharUnicodeInfo.GetUnicodeCategory(c)); } if (!IsAscii(c)) { return CheckNumber(GetLatin1UnicodeCategory(c)); } return ((c >= '0') && (c <= '9')); }
На лицо явное дублирование кода. Начинающий имеет полное право думать, что из первого можно было бы вызвать второй метод, передав ему символ, и избавится от дублирования кода.
Лично я не берусь судить о том, какими инструментами пользовались те, кто принял решение продублировать код, а также о том, как часто подобные методы вызываются самим .NET Framework и что было бы хуже - увеличить количество повторяющегося кода и тем самым - объем библиотеки и требуемой памяти, или же забить стек в случаях, когда кому то придется часто вызывать такие методы.
Но в любом случае на лицо результат - не все приемы, кажущиеся очевидными и порой даже необходимыми - являются подходящими.
Конечно, если кто то подумает, что эта пара методов единственная и разработчики просто завтыкали, то они будут не правы. Для подтверждения ниже привожу пары других методов этой структуры, содержащих продублированный код:
public static bool IsWhiteSpace(char c) | public static bool IsWhiteSpace(string s, int index) |
С другой стороны в следующих методах отказались от дублирования, и вызывают другой метод.
public static bool IsLowSurrogate(string s, int index) вызывает public static bool IsLowSurrogate(char c)
public static bool IsLowSurrogate(string s, int index) вызывает public static bool IsLowSurrogate(char c)
public static bool IsHighSurrogate(string s, int index) вызывает public static bool IsHighSurrogate(char c)
А не может этот код быть результатом оптимизации компилятором? Ведь рефлектор просто переводит байт код в C#... но не буду утверждать ;)
ReplyDelete