Правильно ли я оформил код? C#
Я сделал свою программу, которая решает уравнения. Я сделал проверку: сложения(+), разности(-), произведения(*) и частности(/). В входные данные входят: число, оператор, икс, равно, результат. Я долго писал программу, так как я ещё тренируюсь. Он у меня полностью работает! Но у меня возник вопрос, годен ли мой код? Можно ли его как-то улучшить? Есть ли с ним проблемы(скорее всего). Надеюсь вы мне поможете пожалуйста. Мой код:
using System;
namespace ConsoleApplication2
{
static class Program
{
private static string GetResult(string primer)
{
var split = primer.Split(' ');
var xPosition = Array.IndexOf(split, "x");
var Result = Convert.ToInt32(split[split.Length - 1]);
var OtherDigit = xPosition == 0 ? int.Parse(split[2]) : int.Parse(split[0]);
// Console.WriteLine(xPosition + " --- is position");
var _operator = Convert.ToChar(split[1]);
switch (_operator)
{
case '+':
return $"x = {Result} - {OtherDigit}\n" +
$"x = {Result - OtherDigit}";
case '-':
return xPosition == 0 ? $"x = {Result} + {OtherDigit}\n " + $"x = {Result + OtherDigit}" :
$"x = {OtherDigit} - {Result}\n" + $"x = {OtherDigit - Result}";
case '*':
return $"x = {Result} / {OtherDigit}\n" +
$"x = {Result / OtherDigit}";
case '/':
return xPosition == 0 ? $"x = {OtherDigit} * {Result}\n" + $"x = {OtherDigit * Result}" :
$"x = {OtherDigit} / {Result}\n" + $"x = {OtherDigit / Result}";
}
return "Err0r, s0rry. :(";
}
private static void Main(string[] args)
{
Console.Write("Введите пример: ");
var primer = Console.ReadLine();
Console.WriteLine(primer);
Console.WriteLine(GetResult(primer));
Console.WriteLine("Нажмите на любую клавишу чтобы выйти ...");
Console.ReadKey();
}
}
}
И если что, как тут код записан, так и он записан у меня в JetBrains Rider.
Ответы (1 шт):
Очень качественно у вас намешано. Чем однотипнее оформлен код, тем проще он читается, а соответственно его легче изменить или объяснить другому разработчику, что он делает.
Я не стал трогать логику вашего решения, оставил все как есть, но изменил именно оформление кода.
- Правила именования переменных нарушены. Локальные переменные должны называться с маленькой буквы.
- Перемешана конкантенация и интерполяция строк, надо выбрать что-то одно.
- Вы форматируете выходную строку по одним и тем же правилам каждый раз, почему бы не вынести повторяющийся код в отдельный метод?
- Тернарный оператор тем и хорош, что его можно засунуть насколько угодно глубоко в строчку кода и бонус от этого - убирание повторяющегося кода.
Следите за руками, каждая последующая строчка лучше предыдущей
var OtherDigit = xPosition == 0 ? int.Parse(split[2]) : int.Parse(split[0]);
var OtherDigit = int.Parse(xPosition == 0 ? split[2]: split[0]);
var OtherDigit = int.Parse(split[xPosition == 0 ? 2 : 0]);
var OtherDigit = int.Parse(split[xPosition ^ 2]);
По поводу ^ - это побитовая операция XOR, вы же проходили двоичные операции &, |, ^? Должны были, а если нет - самое время начать.
Переменные, давайте переименуемся:
split- когда что-то разделяется на части, это называется токены -tokens.xPosition- почемуx? у вас же нет никаких других позишнов - простоposition.Result- здесь вообще нет логики, операнды в выражении из 2 операндов называются левый и правый, пусть жто будет левый -left.OtherDigit- "ДругаяЦифра" почему цифра, почему другая... -right_operator- здесь логика есть, вы назвали так, потому что ключевое словоoperatorнельзя использовать для названия переменной, но вы используете эту переменную всего один раз, значит можно вообще без нее обойтись. Кстати, чтобы получить первый символ строки, можно обратиться к нему по индексу[0], вот и получится, чтоvar _operator = Convert.ToChar(split[1])можно было бы записать какvar _operator = split[1][0]primer- транслит, хуже транслита только кириллица. Также у вас же уравнение с одной неизвестной, вот давайте это так и назовем "уравнение" -equation.GetResult()- "получить результат", неплохо, но можно лучше. "вычислить" -Compute()
Err0r, s0rry. :( - как пользователь поймет, что случилось по этой надписи? Вы встречали приложения, которые вам выдают окошко с надписью Произошла ошибка, и больше ничего не выдают? Вот и я не встречал, встречал только Произошла неизвестная ошибка, но это уже другая история. Потом для генерации ошибок есть такая штука - исключения, их можно бросать throw и ловить catch.
private static string Compute(string equation)
{
var tokens = equation.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (tokens.Length != 5)
throw new Exception("Неподдерживаемый формат уравнения");
var position = Array.IndexOf(tokens, "x");
var left = int.Parse(tokens[tokens.Length - 1]);
var right = int.Parse(tokens[position ^ 2]);
switch (tokens[1][0])
{
case '+':
return Format(left, right, '-', left - right);
case '-':
return position == 0
? Format(left, right, '+', left + right)
: Format(right, left, '-', left - right);
case '*':
return Format(left, right, '/', left / right);
case '/':
return position == 0
? Format(right, left, '*', right * left)
: Format(right, left, '/', right / left);
default:
throw new Exception("Неизвестный оператор");
}
}
private static string Format(int left, int right, char action, int result)
{
return $"x = {left} {action} {right}\nx = {result}";
}
private static void Main(string[] args)
{
Console.Write("Введите уравнение: ");
var equation = Console.ReadLine();
Console.WriteLine(equation);
try
{
Console.WriteLine(Compute(equation));
}
catch (Exception ex)
{
Console.WriteLine($"Ошибка: {ex.Message}");
}
Console.WriteLine("Нажмите на любую клавишу чтобы выйти ...");
Console.ReadKey();
}
А если вы пишете код на C# 8.0 или новее, то есть под .NET Core или .NET 5, то есть более свежий и компактный синтаксис, и метод Compute() может выглядеть вот так:
private static string Compute(string primer)
{
var tokens = primer.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (tokens.Length != 5)
throw new Exception("Неподдерживаемый формат уравнения");
var position = Array.IndexOf(tokens, "x");
var left = int.Parse(tokens[^1]); // ^1 - последний элемент, ^2 - предпоследний и т.д.
var right = int.Parse(tokens[position ^ 2]); // а это XOR, не перепутайте
return tokens[1][0] switch
{
'+' => Format(left, right, '-', left - right),
'-' => position == 0 ? Format(left, right, '+', left + right) : Format(right, left, '-', left - right),
'*' => Format(left, right, '/', left / right),
'/' => position == 0 ? Format(right, left, '*', right * left) : Format(right, left, '/', right / left),
_ => throw new Exception("Неизвестный оператор"),
};
}
StringSplitOptions.RemoveEmptyEntries удалит все пустые элементы при разделении строки, они могли возникнуть, если у вас где-то в уравнении вместо одного - например 2 пробела, или больше. То есть каждый элемент массива tokens теперь будет гарантированно не пустой.