Простая учебная задача, но почему-то до моего решения долюбились, в конце объясню, почему долюбились, и почему, в случае C#, это зря было.
И так, задача состоит в том, чтобы всякие кратные единицы перевести в байты (кому надо обратную задачу, либо все во все — пишите в комментарии). Для этого достаточно сделать следующую функцию, исходя из того, что 1 Кб == 1024 Б, 1 Мб = 1024 Кб, 1 Гб = 1024 Мб. В функцию добавим некую переменную-модификатор, для консольного приложения было проще сделать строковую, в ином случае, может и есть сделать отдельный Enum
для единиц, но я обошелся строковой.
Переменная-модификатор (modificator
) принимает строковые значения G
(g
), M
(m
) и K
(k
), соответственно для гига- мега- и килобайта.
Функция получается такая:
public static ulong ToBytes(ulong bytes, string modificator) { ulong Ret = 0; switch (modificator) { case "": { Ret = bytes; } break; case "K": case "k": { Ret = bytes * 1024; } break; case "M": case "m": { Ret = bytes * 1024 * 1024; } break; case "G": case "g": { Ret = bytes * 1024 * 1024 * 1024; } break; default: { throw new ArgumentException("Wrong modificator [" + modificator + "]. Set K(k), M(m), G(g)"); } } return Ret; }
Задача была очень простая, чисто учебная. Консольная программа принимает в качестве одного параметра число с единицей без пробела, т.е. команда вида program.exe 10G
, должна вывести количество байт. Надо ли Enum
городить, ну красиво было бы, но до Enum
‘ов они не добрались 🙂
В основной программе надо отрезать последний символ из параметра, проверить ли является он нужной буквой (K/M/G
) и пересчитать. Если буквы нету, а только цифры — значит оно уже сразу байты.
В функции Main()
отрезаем последний символ от первого параметра командной строки, если он K/M/G
, считаем, что все остальное число, отрезаем его, а все остальное пытаемся сконвертировать в ulong (Int64)
и передать функции ToBytes()
с отрезанным символом, как модификатором для расчета. Если нет — просто считаем, что вся строка число, пытаемся конвертировать, а функции передаем пустой модификатор.
Ошибки конвертации ловим try/catch
:
string size_s = args[1]; try { string mdf = size_s.Substring(size_s.Length - 1, 1); if ((mdf != "K") && (mdf != "k") && (mdf != "M") && (mdf != "m") && (mdf != "G") && (mdf != "g")) { mdf = ""; //in parameter only numbers or param wrong... } else // remove modificator { size_s = size_s.Substring(0, size_s.Length - 1); } BytesCount = ToBytes(Convert.ToUInt64(size_s), mdf); } catch (Exception ex) { Console.WriteLine("Wrong <size> parameter!"); Console.WriteLine(ex.Message); Console.Write("Press Enter..."); Console.ReadLine(); return 2; }
За вот эти вот конструкции:
Ret = bytes * 1024;
Ret = bytes * 1024 * 1024;
Ret = bytes * 1024 * 1024 * 1024;
Типа «ну тут числа, ты бы их сначала перемножил, результат записал , а потом на переменную помножил».
Дебилы, бля, как говорил Лавров. В интерпретируемых языках или старом Трупопоскакале под DOS, может это и какой-то рояль играет, но в C# компилятор перемножает константы до сборки экзешника, а 1024*1024*1024
для компилятора константы, во время компиляции. Т.е. процессору скормят 1073741824
. А код останется более понятен и читабелен.