Re[6]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.04.11 06:37
Оценка: +1
Здравствуйте, xobotik, Вы писали:

X>Если конечно обобщенные методы не устраивают, а необходимо передавать массив byte,

X>то можно воспользоваться следующими материалами, там вроде как решаются похожие задачи с упором на производительность:
X>1) http://codelab.ru/task/cycle_shift/;
X>2) http://habrahabr.ru/blogs/algorithm/101059/;
X>3) http://devels.ru/?what=art&p=486.

1ая и 3яя ссылки — ротация массивов, которая делается без использования дополнительной памяти. Для чего тут эти ссылки, если массив придется пересоздавать для добавления одного элемента? Ротация тут не нужна, ибо можно сделать копирование.
2-ая ссылка вообще о ротации битов
Re[6]: Как не надо писать код
От: AlexNek  
Дата: 10.04.11 10:47
Оценка:
Здравствуйте, xobotik, Вы писали:

x> Если конечно обобщенные методы не устраивают, а необходимо передавать массив byte,

x> то можно воспользоваться следующими материалами, там вроде как решаются похожие задачи с упором на производительность:
Спасибо, конечно. Но вопрос как решить задачу правильно возник спонтанно по "желанию читателей" Кстати, в ссылках ничего полезного не нашел.
x> 1) http://codelab.ru/task/cycle_shift/;
x> 2) http://habrahabr.ru/blogs/algorithm/101059/;
x> 3) http://devels.ru/?what=art&p=486.
avalon 1.0rc3 rev 380, zlib 1.2.3
Re[2]: Как не надо писать код
От: AlexNek  
Дата: 10.04.11 10:47
Оценка:
Здравствуйте, Олег К., Вы писали:

ОК> Зачем создал этот топик? Зайди в соседний форум по плюсам. Там в девяти топиках из десяти увидишь как не надо писать код.

Вообще то для учебных целей Может любители "оптимизации" заглянут
А плюсов я объелся в свое время, потому совсем не тянет туда ходить.
avalon 1.0rc3 rev 380, zlib 1.2.3
Re[4]: Как не надо писать код
От: AlexNek  
Дата: 10.04.11 10:47
Оценка:
Здравствуйте, Олег К., Вы писали:

ОК> AN>Чтобы понять как работает также нужно напрягаться.

ОК> AN>Называется "экономия строк"

ОК> Особенно любит впихнуть как можно больше в одну строку местный мыщьх. Просто обожает оператор "запятая." Это, видать, его последователи.

Я как раз и зациклился на этом коде именно из-за этого (оператор "запятая.") Скобочку справа не заметил
avalon 1.0rc3 rev 380, zlib 1.2.3
Re[6]: Как не надо писать код
От: AlexNek  
Дата: 10.04.11 11:16
Оценка:
Здравствуйте, xobotik, Вы писали: (не могу найти исходное сообщение)

x> x>> То есть допустим на входе массив, необходимо сместить данные на одну позицию влево и добавить что-то в array[0]?


x> AN>Массив 1,2,3,4,5

x> AN>Результат 99,1,2,3,4,5

x>


x> public static T[] AddToStart<T>(this T[] array, T item)

x> {
x> if (array == null) throw new ArgumentNullException("array");

x> T[] newArray = new T[array.Length + 1];

x> newArray[0] = item;

x> for (int i = 0; i < array.Length; i++)

x> {
x> newArray[i + 1] = array[i];
x> }
x> return newArray;
x> }
x>

x> Конечно можно воспользоваться встроенными методами, но мне кажется в таком представлении понять метод не затруднит.


Как минимум вы убрали длину данных, никто не говорил что длина буфера== длине данных.
Кроме этого, для чего генерики? Речь шла о выводе байт (и только байт).
Ну и создавать каждый раз массив несколько накладно по времени, как мне кажется.
Для информации — функция реализует один из методов интерфейса.
Re[7]: Как не надо писать код
От: xobotik Россия  
Дата: 10.04.11 18:36
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, xobotik, Вы писали:


X>>Если конечно обобщенные методы не устраивают, а необходимо передавать массив byte,

X>>то можно воспользоваться следующими материалами, там вроде как решаются похожие задачи с упором на производительность:
X>>1) http://codelab.ru/task/cycle_shift/;
X>>2) http://habrahabr.ru/blogs/algorithm/101059/;
X>>3) http://devels.ru/?what=art&amp;p=486.

S>1ая и 3яя ссылки — ротация массивов, которая делается без использования дополнительной памяти. Для чего тут эти ссылки, если массив придется пересоздавать для добавления одного элемента? Ротация тут не нужна, ибо можно сделать копирование.

S>2-ая ссылка вообще о ротации битов
S>

Да чет в 6 утра затупил=) просто изначально хотел сделать так изменить размер массива (Array.Resize(array, array.Length + 1)), потом сместить вправо все элементы на одну позицию (для этого можно обобщить ротацию).
С уважением!
Re[7]: Как не надо писать код
От: xobotik Россия  
Дата: 10.04.11 18:36
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Здравствуйте, xobotik, Вы писали:


x>> Если конечно обобщенные методы не устраивают, а необходимо передавать массив byte,

x>> то можно воспользоваться следующими материалами, там вроде как решаются похожие задачи с упором на производительность:
AN>Спасибо, конечно. Но вопрос как решить задачу правильно возник спонтанно по "желанию читателей" Кстати, в ссылках ничего полезного не нашел.

Да ссылки не те кинул =)
С уважением!
Re[8]: Как не надо писать код
От: samius Япония http://sams-tricks.blogspot.com
Дата: 10.04.11 18:39
Оценка:
Здравствуйте, xobotik, Вы писали:

X>Да чет в 6 утра затупил=) просто изначально хотел сделать так изменить размер массива (Array.Resize(array, array.Length + 1)), потом сместить вправо все элементы на одну позицию (для этого можно обобщить ротацию).


Resize это уже копирование, только без возможности указать индекс в целевом массиве.
Re[7]: Как не надо писать код
От: xobotik Россия  
Дата: 10.04.11 18:41
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Как минимум вы убрали длину данных, никто не говорил что длина буфера== длине данных.


Не понял) Вы о чем ?)

AN>Кроме этого, для чего генерики? Речь шла о выводе байт (и только байт).


T -> byte не проблема поменять )

AN>Ну и создавать каждый раз массив несколько накладно по времени, как мне кажется.


А как без создания дополнительного массива решать данную задачу ? )

AN>Для информации — функция реализует один из методов интерфейса.


Не понял)

P.S. Сообщение удалял =)
С уважением!
Re[9]: Как не надо писать код
От: xobotik Россия  
Дата: 10.04.11 18:45
Оценка:
Здравствуйте, samius, Вы писали:

S>Здравствуйте, xobotik, Вы писали:


X>>Да чет в 6 утра затупил=) просто изначально хотел сделать так изменить размер массива (Array.Resize(array, array.Length + 1)), потом сместить вправо все элементы на одну позицию (для этого можно обобщить ротацию).


S>Resize это уже копирование, только без возможности указать индекс в целевом массиве.


В курсе =)
С уважением!
Re[8]: Как не надо писать код
От: AlexNek  
Дата: 10.04.11 19:09
Оценка:
Здравствуйте, xobotik, Вы писали:

x> AN>Как минимум вы убрали длину данных, никто не говорил что длина буфера== длине данных.


x> Не понял) Вы о чем ?)

Там в параметрах функции вроде была еше длина данных. Я о том что если переделывать функцию желательно оставаться в пределах ее старых параметров.

x> AN>Кроме этого, для чего генерики? Речь шла о выводе байт (и только байт).


x> T -> byte не проблема поменять )

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

x> AN>Ну и создавать каждый раз массив несколько накладно по времени, как мне кажется.


x> А как без создания дополнительного массива решать данную задачу ? )

Довольно просто, размер буфера в 99.999% случаях меньше длины данных. Новый буфер создается только для теоретического случая когда буфера недостаточно.

x> AN>Для информации — функция реализует один из методов интерфейса.


x> Не понял)

Это по поводу статика. Если нет использования this, еще не значит что можно делать функцию статик.
Вообще то это все не так важно, как то что вы захотели предложить свой вариант, просто, мне кажется, что возможно, данные замечания могут пригодится при командной работе. (Особенно удаленной) Ну представьте себе, вам показали старую функцию, немного пояснили и сказали сделать лучше. В итоге, вы присылаете свой вариант.

x> P.S. Сообщение удалял =)

Теперь уже поняли, появилась новая проблема работы с оффлайн бровсерами
avalon 1.0rc3 rev 380, zlib 1.2.3
Re[8]: Как не надо писать код
От: AlexNek  
Дата: 10.04.11 19:09
Оценка:
Здравствуйте, xobotik, Вы писали:

x> x>> Если конечно обобщенные методы не устраивают, а необходимо передавать массив byte,

x> x>> то можно воспользоваться следующими материалами, там вроде как решаются похожие задачи с упором на производительность:

x> AN>Спасибо, конечно. Но вопрос как решить задачу правильно возник спонтанно по "желанию читателей" Кстати, в ссылках ничего полезного не нашел.


x> Да ссылки не те кинул =)

Сорри, это было мне не узнать.
avalon 1.0rc3 rev 380, zlib 1.2.3
Re[9]: Как не надо писать код
От: xobotik Россия  
Дата: 10.04.11 19:36
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Там в параметрах функции вроде была еше длина данных. Я о том что если переделывать функцию желательно оставаться в пределах ее старых параметров.


public void WriteTransformation(ref byte[] buffer, ref int bufferLength, WriteByteHandler writeByteHandler)


То есть int bufferLength это длина совершенно другого какого то буфера?) То есть buffer.Length != bufferLength?

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


Согласен, но вы же сами сказали http://rsdn.ru/forum/dotnet/4227826.1.aspx
Автор: AlexNek
Дата: 10.04.11


AN>Довольно просто, размер буфера в 99.999% случаях меньше длины данных. Новый буфер создается только для теоретического случая когда буфера недостаточно.


То есть задача состоит в следующем:
есть какие либо данные, есть длина этих данных, есть константа PREFIX. Данные содержаться в массиве buffer длиной bufferLength -> N, сам массив длиной buffer.Length -> M. Необходимо добавить в начало PREFIX. Если N == M || N > M, то создаем новый массив, копируем все данные в новый массив, добавляем PREFIX (и эта ситуация с вероятностью 0.001). Если N < M смещаем данные в исходном массиве buffer на одну позицию вправо и записываем PREFIX в начало. Так же необходимо вернуть новую длину данных, а это всегда N + 1.

Следуя из сигнатуры метода, buffer -> массив, в котором содержаться данные длины bufferLength это так ?

AN>Это по поводу статика. Если нет использования this, еще не значит что можно делать функцию статик.

AN>Вообще то это все не так важно, как то что вы захотели предложить свой вариант, просто, мне кажется, что возможно, данные замечания могут пригодится при AN>командной работе. (Особенно удаленной) Ну представьте себе, вам показали старую функцию, немного пояснили и сказали сделать лучше. В итоге, вы присылаете свой AN>вариант.

Просто не понял постановки задачи=)

x>> P.S. Сообщение удалял =)

AN>Теперь уже поняли, появилась новая проблема работы с оффлайн бровсерами

Не понял)
С уважением!
Re[2]: Как не надо писать код
От: Lloyd Россия  
Дата: 10.04.11 20:04
Оценка:
Здравствуйте, SergeyT., Вы писали:

ST>Более того, я осмелился этот код переписать. Вот что у меня вышло:


ST>
ST>public byte[] WriteTransformation(byte[] buffer, int bufferLength)

Так ли это уж хорошо в данном случае менять сигнутуру? В первом варианте было понятно, что buffer может поменяться, тут же надо знать реализацию.

ST>{
ST>    // Выделяем проверку предусловий в отдельный блок, что на порядок упрощает весь остальной код.

И возможно ломает существующий код. :)

ST>    // Контракты просто упрощают запись, но никто не мешает проверить предусловия руками.
ST>    Contract.Requires(buffer != null);
ST>    Contract.Requires(bufferLength >= 0);
ST>    Contract.Ensures(Contract.Result<byte[]>() != null);

Ни одного из этих предусловий нет в коде.

ST>    // Прежде всего убираем не используемый параметр, 

Неиспользуемый? 
[q]
if (writeByteHandler != null)
[/q]

ST>если же он используется, то добавляем
ST>    // соответствующее предусловие.

Какое? И что вы будете возвращать, если writeByteHandler == null. У вас же Contract.Ensures(Contract.Result<byte[]>() != null) :)

ST>    // А теперь демонстрируем уличную магию того, как проверка предусловий упрощает код:
ST>    // Было: bufferLength = 1 + Math.Min(Math.Max(bufferLength, 0), (buffer != null) ? buffer.Length : 0);
ST>    // Меняем: (buffer != null) ? buffer.Length : 0 --> buffer.Length, благодаря buffer != null
ST>    // Меняем: Math.Max(bufferLength, 0) --> bufferLength, благодаря bufferLength >= 0
ST>    // Добавляем комментарий и вот, что мы получаем в итоге:
            
ST>    // Необходимость +1 обусловлена тем, что в нулевой байт выходного буфера мы поместим PREFIX
ST>    bufferLength = 1 + Math.Min(bufferLength, buffer.Length);

Переиспользование переменной для разных нужд. Фаулер негодуэ. :)

ST>    byte[] newBuffer;

ST>    // Теперь меняем следующий код:
ST>    // Было: if (bufferLength - 1 < ((buffer != null) ? buffer.Length : 0))
ST>    // Проверка buffer != null, уже не нужна
ST>    // Получаем: if (buffer.Length > bufferLength - 1)
ST>    // Заменяем > на >=:
ST>    // if (buffer.Lengh >= bufferLength)
ST>    // Инвертируем логику, поскольку она проще
ST>    // Результат: if (buffer.Lenfth < bufferLenfth) ...
ST>    // Добавляем комментарий и вот, что получаем в результате:

ST>    // Нам нужно удостовериться, что в исходном массиве есть место под дополнительный
ST>    // байт префикса:
ST>    if (buffer.Length < bufferLength )
ST>    {
ST>        newBuffer = new byte[bufferLength];
ST>    }
ST>    else
ST>    {
ST>        newBuffer = buffer;
ST>    }

ST>    // Все, что удалось улучшить в этом коде, так это избавиться от лишних
ST>    // проверок и добавить комментарий, поясняющий причину перебора элементов
ST>    // "справа". Кстати, Array.CopyTo здесь не подойдет, поскольку он копирует
ST>    // *все* элементы массива, а реальный размер массива buffer может быть большим

Зато подойдет Array.Copy :)

ST>    // Добавляем комментарий:
ST>    // Теперь нам нужно скопировать все элементы из массива buffer в newBuffer, сместив
ST>    // каждый из них на  один индекс вправо, чтобы в нулевой индекс поместить PREFIX

Имхо, единственный нетривиальный момент этого кода (обратный ход цикла) вы и не удосужились откомментировать.

ST>    for (int i = bufferLength - 1; i > 0; i--)
ST>    {
ST>        newBuffer[i] = buffer[i - 1];
ST>    }

ST>    // Здесь тоже проверка уже не нужна
ST>    newBuffer[0] = PREFIX;

ST>    // У нас все еще есть проблема, поскольку в некоторых случаях мы меняем переданный буфер,
ST>    // так что, если размер этого массива обычно небольшой, то я бы предпочел, чтобы всегда
ST>    // возвращался новый объект.
ST>    // Неизменяемость (или имутабельность) - это отличная техника программирования!
ST>    return newBuffer;
ST>}
ST>
Re[10]: Как не надо писать код
От: AlexNek  
Дата: 10.04.11 20:23
Оценка: 2 (1)
Здравствуйте, xobotik, Вы писали:

x> AN>Там в параметрах функции вроде была еше длина данных. Я о том что если переделывать функцию желательно оставаться в пределах ее старых параметров.


x>
x> public void WriteTransformation(ref byte[] buffer, ref int bufferLength, WriteByteHandler writeByteHandler)
x>


x> То есть int bufferLength это длина совершенно другого какого то буфера?) То есть buffer.Length != bufferLength?

Правильнее было было бы назвать эту переменную по другому, типа "длина данных" в буфере.

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


x> Согласен, но вы же сами сказали http://rsdn.ru/forum/dotnet/4227826.1.aspx
Автор: AlexNek
Дата: 10.04.11


А что в том примере неправильно?

x> AN>Довольно просто, размер буфера в 99.999% случаях меньше длины данных. Новый буфер создается только для теоретического случая когда буфера недостаточно.


x> То есть задача состоит в следующем:

x> есть какие либо данные, есть длина этих данных, есть константа PREFIX. Данные содержаться в массиве buffer длиной bufferLength -> N, сам массив длиной buffer.Length -> M. Необходимо добавить в начало PREFIX. Если N == M || N > M, то создаем новый массив, копируем все данные в новый массив, добавляем PREFIX (и эта ситуация с вероятностью 0.001). Если N < M смещаем данные в исходном массиве buffer на одну позицию вправо и записываем PREFIX в начало. Так же необходимо вернуть новую длину данных, а это всегда N + 1.

x> Следуя из сигнатуры метода, buffer -> массив, в котором содержаться данные длины bufferLength это так ?

Вроде все так, по крайней мере пока ничего не заметил, во всяком случае "старая" функция работает правильно. Кстати вероятность взята "с потолка".

x> AN>Это по поводу статика. Если нет использования this, еще не значит что можно делать функцию статик.

x> AN>Вообще то это все не так важно, как то что вы захотели предложить свой вариант, просто, мне кажется, что возможно, данные замечания могут пригодится при AN>командной работе. (Особенно удаленной) Ну представьте себе, вам показали старую функцию, немного пояснили и сказали сделать лучше. В итоге, вы присылаете свой AN>вариант.

x> Просто не понял постановки задачи=)

Типичная проблема, которую весьма трудно обнаружить

x> x>> P.S. Сообщение удалял =)


x> AN>Теперь уже поняли, появилась новая проблема работы с оффлайн бровсерами


x> Не понял)

Вы наверное еще не были в разделе "открытые проекты" и RSDN@Home? Я тоже раньше не был, но потом попробовал и весьма понравилось. Кстати, огромнейший простор для применения своих сил. Рекомендую начать ознакомление с avalon-а, а потом можно приняться и за янус. Наоборот лучше не делать, останется неприятный осадок.
avalon 1.0rc3 rev 380, zlib 1.2.3
Re[3]: Как не надо писать код
От: SergeyT. США http://sergeyteplyakov.blogspot.com/
Дата: 10.04.11 21:41
Оценка:
Здравствуйте, Lloyd, Вы писали:

ST>>
ST>>public byte[] WriteTransformation(byte[] buffer, int bufferLength)


L>Так ли это уж хорошо в данном случае менять сигнутуру? В первом варианте было понятно, что buffer может поменяться, тут же надо знать реализацию.


Ну, тут каждому свое. Я бы сделал buffer неизменяемым если это возможно (т.е. не накладно). А то, что мы все равно можем изменить передаваемый буфер (путем изменения его содержимого, а не переменной) это тоже плохо. Я, кстати, об этом в самом низу сказал.

ST>>{

ST>> // Выделяем проверку предусловий в отдельный блок, что на порядок упрощает весь остальной код.

L>И возможно ломает существующий код.


Ну, я бы поискал все использования существующего кода. А вообще, очень злая проблема многих систем — умалчивание глюков. Вот и получается, мы переходим на новую версию системы, которая строже относится к своей работе и получаем кучу ошибок. Так что да, я бы добавил предусловия даже ценой поломки кода. Хотя никто не мешает просто вернуть управление из метода сразу. Это тоже будет проверкой предусловия, просто в данном случае постусловие будет отсутствовать.

ST>> // Контракты просто упрощают запись, но никто не мешает проверить предусловия руками.

ST>> Contract.Requires(buffer != null);
ST>> Contract.Requires(bufferLength >= 0);
ST>> Contract.Ensures(Contract.Result<byte[]>() != null);

L>Ни одного из этих предусловий нет в коде.

Я осмелился их добавить. Кстати, все предусловия есть в коде в неявном виде. Посмотри внимательно на все проверки buffer != null. Фактически — это и есть предусловие. Т.е. если buffer == null, то никакая работа в методе не выполнится. Кроме того, проверка на bufferLength >= 0 тоже присутствует. Она зашита в этом:
bufferLength = 1 + Math.Min(Math.Max(bufferLength, 0), (buffer != null) ? buffer.Length : 0);

Только разница в этом случае в том, что если buffer == null — мы ничего не делаем, а если bufferLength < 0 — то мы сей факт просто игнорируем.

Ведь по сути это и есть определение предусловия, т.е. что должно выполнить вызывающий код, чтобы метод выполнил свою работу.

ST>> // Прежде всего убираем не используемый параметр,


L>Неиспользуемый?

L>

L>if (writeByteHandler != null)


Я рассматриваю этот код, как законченный фрагмент кода. В данном случае проверка есть, но другого использования нет. В случае топик-стартера я не знаю, есть ли это использование на самом деле или нет, я же в своих рассуждениях отталкиваюсь от того, что приведенный здесь код полный.

ST>>если же он используется, то добавляем

ST>> // соответствующее предусловие.

L>Какое? И что вы будете возвращать, если writeByteHandler == null. У вас же Contract.Ensures(Contract.Result<byte[]>() != null)


Если он используется и является ключевым для работы метода, то я добавляю предусловие writeByteHandler != null. Если это не является предусловием, например, если этот делегат используется для переопределения поведения по-умолчанию (может для замены того самого первого байта), то предусловие убираем. При этом это никак не влияет на постусловие.

Кроме того, повторюсь еще раз: использование Code Contracts в этом примере — это лишь механизм, а не пошаговая инструкция. Ты можешь заменить Code Contracts на генерацию исключений или просто на выход из метода. Да это будет не пофеншую с точки зрения дядьки Мейера, но тем не менее, неявный контракт метода будет присутствовать, просто он будет звучать не как: "если вы мне передали хрень — я сгенерю исключение", а так: "если вы мне передали хрень — я ничего не буду делать и просто верну управление". Решать нужно на месте, в большинстве случаев я бы генерил исключение, как бы поступл ты — хз.

ST>> // А теперь демонстрируем уличную магию того, как проверка предусловий упрощает код:

ST>> // Было: bufferLength = 1 + Math.Min(Math.Max(bufferLength, 0), (buffer != null) ? buffer.Length : 0);
ST>> // Меняем: (buffer != null) ? buffer.Length : 0 --> buffer.Length, благодаря buffer != null
ST>> // Меняем: Math.Max(bufferLength, 0) --> bufferLength, благодаря bufferLength >= 0
ST>> // Добавляем комментарий и вот, что мы получаем в итоге:

ST>> // Необходимость +1 обусловлена тем, что в нулевой байт выходного буфера мы поместим PREFIX

ST>> bufferLength = 1 + Math.Min(bufferLength, buffer.Length);

L>Переиспользование переменной для разных нужд. Фаулер негодуэ.


Да, я тут заметку по этому поводу ваяю, там я уже добавил newBufferLength. Прости, посыпаю голову пеплом, что сразу не зделал все, как нужно

ST>> // Все, что удалось улучшить в этом коде, так это избавиться от лишних

ST>> // проверок и добавить комментарий, поясняющий причину перебора элементов
ST>> // "справа". Кстати, Array.CopyTo здесь не подойдет, поскольку он копирует
ST>> // *все* элементы массива, а реальный размер массива buffer может быть большим

L>Зато подойдет Array.Copy


Ага. Вот эту перегруженную версию метода Copy я что-то проглядел.

ST>> // Добавляем комментарий:

ST>> // Теперь нам нужно скопировать все элементы из массива buffer в newBuffer, сместив
ST>> // каждый из них на один индекс вправо, чтобы в нулевой индекс поместить PREFIX

L>Имхо, единственный нетривиальный момент этого кода (обратный ход цикла) вы и не удосужились откомментировать.


Опять, повторюсь, после ревизии я добавил коммент, что проход цикла справа обусловлен тем, что buffer и newBuffer могут указывать на один и тот же объект массива, хотя по новому коду понять причину этого уже несколько проще, не находишь? Но, конечно же, вариант с Copy идеальный, ибо мы получаем такой себе memmove.

ST>> for (int i = bufferLength — 1; i > 0; i--)

ST>> {
ST>> newBuffer[i] = buffer[i — 1];
ST>> }

ST>> // Здесь тоже проверка уже не нужна

ST>> newBuffer[0] = PREFIX;
Re[11]: Как не надо писать код
От: xobotik Россия  
Дата: 10.04.11 22:22
Оценка:
Здравствуйте, AlexNek, Вы писали:

x>> То есть int bufferLength это длина совершенно другого какого то буфера?) То есть buffer.Length != bufferLength?

AN>Правильнее было было бы назвать эту переменную по другому, типа "длина данных" в буфере.

Вы правы=)

x>> Согласен, но вы же сами сказали http://rsdn.ru/forum/dotnet/4227826.1.aspx
Автор: AlexNek
Дата: 10.04.11


AN>А что в том примере неправильно?


Да все правильно, просто я его дословно понял, поэтому и написал метод AddToFirst))

AN>Вы наверное еще не были в разделе "открытые проекты" и RSDN@Home?


Неа =) надо покурить этот хоум=)

AN>Я тоже раньше не был, но потом попробовал и весьма понравилось. Кстати, огромнейший простор для применения своих сил. Рекомендую начать ознакомление с avalon-а, а потом можно приняться и за янус. Наоборот лучше не делать, останется неприятный осадок.


Avalon прикольная штука=)) буду юзать, спасибо =)

А по поводу задачки, ну вот вроде решил:
        public void WriteTransformation(ref byte[] buffer, ref int dataLength, WriteByteHandler handler)
        {
            if (buffer == null) return;
            if (dataLength < 0) return;
            if (handler == null) return;

            if (dataLength < buffer.Length)
            {
                for (int i = dataLength; i > 0; i--)
                {
                    buffer[i] = buffer[i - 1];
                }
                buffer[0] = PREFIX;
            }
            if (dataLength >= buffer.Length)
            {
                byte[] newArray = new byte[dataLength + 1];
                for (int i = 0; i < buffer.Length; i++)
                {
                    newArray[i + 1] = buffer[i];
                }
                newArray[0] = PREFIX;
                buffer = newArray;
            }
            dataLength++;
        }

P.S. Конечно можно было выделить как минимум один дополнительный метод это сдвиг элементов массива в право на N позиций,
но стоит задача в рамках одного метода реализовать, как я понял.
Так же конечно можно было воспользоваться встроенным методом Array.Copy вместо участка кода:
for (int i = 0; i < buffer.Length; i++)
{
    newArray[i + 1] = buffer[i];
}

код:
Array.Copy(buffer, 0, newArray, 1, buffer.Length);

но как-то нарушается эстетика всего метода, а конкретнее симметрия, чисто мое мнение =)
Да и еще не рассмотрел случай, когда передается пустой buffer, но dataLength отлична и больше нуля, надо ли рассматривать такой случай?
С уважением!
Re: Как не надо писать код
От: sergey_shandar США http://getboost.codeplex.com/
Дата: 11.04.11 07:19
Оценка:
Здравствуйте, AlexNek, Вы писали:

AN>Что то часто мне стал попадаться код в который сразу не врубишься, при этом код делает свою задачу правильно.


Один вопрос: человек до этого кодил на C или C++? А то у меня Deja vu.
getboost.codeplex.com
citylizard.codeplex.com
Re: Как не надо писать код
От: Powerz Россия https://zagosk.in
Дата: 11.04.11 08:46
Оценка: -2 :)
Здравствуйте, AlexNek, Вы писали:

Задача: на вход поступает int, надо вернуть последнюю цифру.
Собственно шедевр (имя метода и входного параметра изменено, все совпадения чистая случайность):

public static string GetX(int id)
{
    return id.ToString().Substring(id.ToString().Length - 1, 1);
}


Писал не какой-нибудь джуниор, а программист-архитектор-тимлид.

Переписано так:

public static int GetX(int id)
{
    return id % 10;
}
https://zagosk.in
Re[2]: Как не надо писать код
От: AlexNek  
Дата: 11.04.11 16:31
Оценка:
Здравствуйте, Powerz, Вы писали:

P> Задача: на вход поступает int, надо вернуть последнюю цифру.

P> Собственно шедевр (имя метода и входного параметра изменено, все совпадения чистая случайность):

P>
P> public static string GetX(int id)
P> {
P>     return id.ToString().Substring(id.ToString().Length - 1, 1);
P> }
P>


P> Писал не какой-нибудь джуниор, а программист-архитектор-тимлид.


P> Переписано так:


P>
P> public static int GetX(int id)
P> {
P>     return id % 10;
P> }
P>


Это шедевр нормальному человеку до такого не додуматься, а умному запросто.
avalon 1.0rc3 rev 380, zlib 1.2.3
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.