Подсчет калорий

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

Прежде чем кто-нибудь скажет мне, да, я должен исправить глобальные переменные. Я бы хотел сделать это шаг за шагом. Я думал о том, чтобы реализовать их локально и передавать их, но, конечно, это потребует некоторой реконструкции кода, поэтому я надеялся сначала посоветоваться о структуре и общей чистоте кода, чтобы я мог двигаться дальше.

Как примечание, что лучший способ избежать глобальных переменных?

Переменные

public struct FoodRelated
{
    //Variabled directly linked to food or the creation of the food table.

    static Dictionary<int, string> foodNameList = new Dictionary<int, string> ();

    public static Dictionary<int, string> FoodNameList {
        get {
            return foodNameList;
        }
        set {
            foodNameList = value;
        }
    }

    static Dictionary<int, float> servingSizeList = new Dictionary<int, float> ();

    public static Dictionary<int, float> ServingSizeList {
        get {
            return servingSizeList;
        }
        set {
            servingSizeList = value;
        }
    }

    static Dictionary<int, float> caloriesPerServingList = new Dictionary<int, float> ();

    public static Dictionary<int, float> CaloriesPerServingList {
        get {
            return caloriesPerServingList;
        }
        set {
            caloriesPerServingList = value;
        }
    }

    static Dictionary<int, string> definersList = new Dictionary<int, string> ();

    public static Dictionary<int, string> DefinersList {
        get {
            return definersList;
        }
        set {
            definersList = value;
        }
    }

    static readonly float totalCaloriesPerDay = 2140f;

    public static float TotalCaloriesPerDay {
        get {
            return totalCaloriesPerDay;
        }
    }

    public static float Calories {
        get;
        set;
    }

}

public struct GlobalVariables
{
    //Misc global variables

    public static int SelectedListItem {
        get;
        set;
    }

    public static bool ExactSearch {
        get;
        set;
    }

    public static bool AddItem {
        get;
        set;
    }

    static readonly DateTime nowDate = DateTime.Now;

    public static DateTime NowDate {
        get {
            return nowDate;
        }
    }

    public static DateTime dateReset;

    static readonly string registryAppenedValue = "SOFTWARE\\Wow6432Node\\";

    public static string RegistryAppenedValue {
        get {
            return registryAppenedValue;
        }
    }

    const string weightWatchingProgram = "Weight Watching Program+";

    public static string registryMainValue = weightWatchingProgram;

    public static Form mainForm {
        get;
        set;
    }
}

Программа:

using System;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Microsoft.Win32;


namespace Weight_Watching_Program
{
/// <summary>
/// Main Window and all tabs.
/// </summary>
public partial class MainForm : Form
{
    public MainForm ()
    {
        //
        // The InitializeComponent() call is required for Windows Forms designer support.
        //
        InitializeComponent ();

        //
        GlobalVariables.mainForm = this;
        Functions.InitializeForms (foodList, calorieRadioButton, timeRadioButton, caloriesLabel, Seperator1, Seperator2, howManyServingsLabel, searchBar, deleteSelectedFoodItemButton,
            clearSearchBarButton, foodNameEditBox, definerEditBox, servingSizeEditBox, caloriesPerServingEditBox, manualCalorieEditBox);

        //
    }

    //MAIN//
    protected internal virtual void SearchBarTextChanged (object sender, EventArgs e)
    {
        if (!string.IsNullOrEmpty (searchBar.Text) && !Equals (searchBar.Text, " ")) {
            Functions.find (0, searchBar.Text, null, GlobalVariables.ExactSearch, foodList);
            return;
        }
        foodList.ClearSelected ();
    }

    protected internal void searchBarFocusGranted (object sender, EventArgs e)
    {
        searchBar.Clear ();
        clearSearchBarButton.Enabled = true;
        Font tempfont = new Font ("Times New Roman", 10f);
        searchBar.Font = tempfont;
    }

    protected internal void clearSearchBarButtonClicked (object sender, EventArgs e)
    {
        searchBar.Clear ();
        clearSearchBarButton.Enabled = false;
        Font tempfont = new Font ("Microsoft Sans Serif", 8.25f, FontStyle.Italic);
        searchBar.Font = tempfont;
        searchBar.Text = "Click Here to Search the Food List";
        searchBar.TextAlign = HorizontalAlignment.Center;
    }

    protected internal virtual void foodListSelectedIndexChanged (object sender, EventArgs e)
    {
        if (foodList.SelectedIndex > -1) {
            GlobalVariables.SelectedListItem = foodList.SelectedIndex;
            howManyServingsLabel.Text = string.Format ("How many {0}s do you plan on eating?", FoodRelated.DefinersList [foodList.SelectedIndex]);
            foodNameEditBox.Text = FoodRelated.FoodNameList [foodList.SelectedIndex];
            foodNameEditBox.TextAlign = HorizontalAlignment.Center;
            servingSizeEditBox.Text = FoodRelated.ServingSizeList [foodList.SelectedIndex].ToString ();
            servingSizeEditBox.TextAlign = HorizontalAlignment.Center;
            definerEditBox.Text = FoodRelated.DefinersList [foodList.SelectedIndex];
            definerEditBox.TextAlign = HorizontalAlignment.Center;
            caloriesPerServingEditBox.Text = FoodRelated.CaloriesPerServingList [foodList.SelectedIndex].ToString ();
            caloriesPerServingEditBox.TextAlign = HorizontalAlignment.Center;
        }
    }

    protected internal void foodListLeaveFocus (object sender, EventArgs e)
    {
        if (Equals (deleteSelectedFoodItemButton.Enabled, true) && foodList.Items.Count <= 0) {
            deleteSelectedFoodItemButton.Enabled = false;
        }
        foodList.ClearSelected ();
    }

    protected internal void foodListEnterFocus (object sender, EventArgs e)
    {
        GlobalVariables.SelectedListItem = foodList.SelectedIndex;
        if (Equals (deleteSelectedFoodItemButton.Enabled, false) && foodList.Items.Count > 0) {
            deleteSelectedFoodItemButton.Enabled = true;
        }
    }

    protected internal void deleteFoodItemFromTable (object sender, EventArgs e)
    {
        Functions.dumpFoodPropertiesList (foodNameEditBox, servingSizeEditBox, caloriesPerServingEditBox, definerEditBox);
        FoodRelated.FoodNameList.Remove (GlobalVariables.SelectedListItem);
        Storage.writeFoodTable ("Text Files\\", "food.table", new string[] {
            null,
            null,
            null,
            null
        }
        );
        Functions.refresh_foodList (foodList);
    }

    protected internal void setFoodPropertiesButtonClicked (object sender, EventArgs e)
    {
        string oldtext = foodNameEditBox.Text;
        Functions.foodPropertiesSwitch (foodList, foodNameEditBox, servingSizeEditBox, caloriesPerServingEditBox, definerEditBox, newItemCheckbox);
        Functions.find (0, oldtext, null, true, foodList);
    }

    protected internal void subtractCalories (object sender, EventArgs e)
    {
        float tempcalories = Functions.modifyCalories (userServingInputTextBox, false);
        bool safetosubtract = false;
        if (FoodRelated.Calories - tempcalories < 0) {
            DialogResult dialogResult = MessageBox.Show ("The amount of calories that are about to be subtracted would put you below your daily limit! Continue?", "You're overeating!", MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2);
            switch (dialogResult) {
            case DialogResult.Yes:
                safetosubtract = true;
                break;
            }
        } else {
            safetosubtract = true;
        }
        switch (safetosubtract) {
        case true:
            FoodRelated.Calories = FoodRelated.Calories - tempcalories;
            break;
        }
        Storage.writeRegistry (GlobalVariables.RegistryAppenedValue, GlobalVariables.registryMainValue, false);
        Validation.checkCurrentRadioButton (timeRadioButton, calorieRadioButton, caloriesLabel);
        userServingInputTextBox.Value = 1;

    }

    protected internal void addCalories (object sender, EventArgs e)
    {
        float tempcalories = Functions.modifyCalories (userServingInputTextBox, true);
        if (FoodRelated.Calories + tempcalories > 2140f) {
            ErrorHandler.errorMessageBox ("The amount of calories that you are trying to add would put you over your daily limit, and is not allowed.", addCaloriesButtonMain, 1, false);
        } else {
            FoodRelated.Calories = FoodRelated.Calories + tempcalories;
        }
        Storage.writeRegistry (GlobalVariables.RegistryAppenedValue, GlobalVariables.registryMainValue, false);
        Validation.checkCurrentRadioButton (timeRadioButton, calorieRadioButton, caloriesLabel);
        userServingInputTextBox.Value = 1;
    }

    protected internal void findNextSearchItem (object sender, EventArgs e)
    {
        if (string.IsNullOrEmpty (searchBar.Text) || Equals (searchBar.Text, " ")) {
            return;
        }
        if (GlobalVariables.SelectedListItem >= foodList.Items.Count - 1) {
            Functions.find (0, searchBar.Text, null, GlobalVariables.ExactSearch, foodList);
        } else {
            Functions.find (GlobalVariables.SelectedListItem, searchBar.Text, FoodRelated.FoodNameList [GlobalVariables.SelectedListItem], GlobalVariables.ExactSearch, foodList);
        }
    }

    protected internal void ExactSearchCheckBoxCheckedChanged (object sender, EventArgs e)
    {
        GlobalVariables.ExactSearch = exactSearchCheckBox.Checked;
    }

    protected internal void CalorieRadioButtonCheckedChanged (object sender, EventArgs e)
    {
        Validation.checkCurrentRadioButton (timeRadioButton, calorieRadioButton, caloriesLabel);
    }

    protected internal void TimeRadioButtonCheckedChanged (object sender, EventArgs e)
    {
        Validation.checkDateValidity (GlobalVariables.NowDate, GlobalVariables.dateReset, Storage.checkRegistryValues (GlobalVariables.RegistryAppenedValue, GlobalVariables.registryMainValue));
        Validation.checkCurrentRadioButton (timeRadioButton, calorieRadioButton, caloriesLabel);
    }

    protected internal void NewItemCheckboxCheckedChanged (object sender, EventArgs e)
    {
        Functions.dumpFoodPropertiesList (foodNameEditBox, servingSizeEditBox, caloriesPerServingEditBox, definerEditBox);
        GlobalVariables.AddItem = newItemCheckbox.Checked;
        foodPropertiesButton.Text = newItemCheckbox.Checked ? "Add this new food item" : "Set Food Item Properties";
    }

    protected internal void resetCaloriesButtonClicked (object sender, EventArgs e)
    {
        manualCalorieEditBox.Value = (decimal)FoodRelated.TotalCaloriesPerDay;
    }

    protected internal void zeroOutCaloriesButtonClicked (object sender, EventArgs e)
    {
        manualCalorieEditBox.Value = 0;
    }

    protected internal void manualSubmitButtonClicked (object sender, EventArgs e)
    {
        FoodRelated.Calories = (float)manualCalorieEditBox.Value;
        Storage.writeRegistry (GlobalVariables.RegistryAppenedValue, GlobalVariables.registryMainValue, false);
        Validation.checkCurrentRadioButton (timeRadioButton, calorieRadioButton, caloriesLabel);
    }

    protected internal void RefreshCaloriesTimeButtonClick (object sender, EventArgs e)
    {
        Validation.checkDateValidity (GlobalVariables.NowDate, GlobalVariables.dateReset, Storage.checkRegistryValues (GlobalVariables.RegistryAppenedValue, GlobalVariables.registryMainValue));
        Validation.checkCurrentRadioButton (timeRadioButton, calorieRadioButton, caloriesLabel);
    }

    //MAIN//
}

public static class Validation
{

    //Functions whose primary purpose is verification and validation, but who don't have a more pressing function.

    public static void checkDateValidity (DateTime dateToCompareTo, DateTime dateToCheck, bool firstProgramUse)
    {
        const bool b = true;
        Storage.readRegistry (GlobalVariables.RegistryAppenedValue, GlobalVariables.registryMainValue);
        if (!Equals (DateTime.Compare (dateToCompareTo, dateToCheck), -1) || firstProgramUse == b) {
            if (Equals (Registry.LocalMachine.OpenSubKey (GlobalVariables.RegistryAppenedValue + GlobalVariables.registryMainValue), null)) {
                Registry.LocalMachine.CreateSubKey (GlobalVariables.RegistryAppenedValue + GlobalVariables.registryMainValue);
            }
            Storage.writeRegistry (GlobalVariables.RegistryAppenedValue, GlobalVariables.registryMainValue, b);
        }
    }

    public static void checkCurrentRadioButton (RadioButton timeRadioButton, RadioButton calorieRadioButton, Label caloriesLabel)
    {
        const bool b = true;
        if (Equals (timeRadioButton.Checked, b)) {
            Functions.writeToObject (caloriesLabel, 1);
        } else if (Equals (calorieRadioButton.Checked, b)) {
            Functions.writeToObject (caloriesLabel, 0);
        }
    }

    public static bool Contains (this string source, string toCheck, StringComparison comp)
    {
        return source.IndexOf (toCheck, comp) >= 0;
    }

}

public static class Functions
{
    //      General functions

    public static void writeToObject (Label labelToChange, int objectNumber)
    {
        string[] messages = {
            string.Format ("Calories Left For The Day: {0}", FoodRelated.Calories),
            string.Format ("Calories will reset on {0:MMMM dd} at {1:hh:mm tt}", GlobalVariables.dateReset, GlobalVariables.dateReset)

        };
        var font = new Font ("Microsoft Sans Serif", 12f, FontStyle.Bold);
        Font[] fontStyle = {
            font,
            font

        };
        var middleCenter = ContentAlignment.MiddleCenter;
        ContentAlignment[] objectAlignment = {
            middleCenter,
            middleCenter

        };
        if (Equals (labelToChange, null))
            return;
        labelToChange.Font = fontStyle [objectNumber];
        labelToChange.Text = messages [objectNumber];
        labelToChange.TextAlign = objectAlignment [objectNumber];
    }

    public static void InitializeForms (ListBox foodList, RadioButton calorieRadioButton, RadioButton timeRadioButton, Label caloriesLabel, Label Seperator1,
                                        Label Seperator2, Label howManyServingsLabel, TextBox searchBar, Button deleteSelectedFoodItemButton,
                                        Button clearSearchBarButton, TextBox foodNameEditBox, TextBox definerEditBox, NumericUpDown servingSizeEditBox,
                                        NumericUpDown caloriesPerServingEditBox, NumericUpDown manualCalorieEditBox)
    {

        const BorderStyle fixed3D = BorderStyle.Fixed3D;
        const HorizontalAlignment center = HorizontalAlignment.Center;
        const bool b = true;
        GlobalVariables.mainForm.Text = GlobalVariables.registryMainValue;
        calorieRadioButton.Checked = b;
        caloriesLabel.BorderStyle = fixed3D;
        Seperator1.AutoSize = false;
        Seperator1.BorderStyle = fixed3D;
        Seperator1.Width = 1;
        searchBar.TextAlign = center;
        Seperator2.AutoSize = false;
        Seperator2.BorderStyle = fixed3D;
        Seperator2.Height = 2;
        searchBar.TextAlign = center;
        refresh_foodList (foodList);
        Validation.checkDateValidity (GlobalVariables.NowDate, GlobalVariables.dateReset, Storage.checkRegistryValues (GlobalVariables.RegistryAppenedValue, GlobalVariables.registryMainValue));
        deleteSelectedFoodItemButton.Enabled = false;
        clearSearchBarButton.Enabled = false;
        foodList.SetSelected (0, b);
        GlobalVariables.SelectedListItem = 0;
        howManyServingsLabel.Text = string.Format ("How many {0}s do you plan on eating?", FoodRelated.DefinersList [GlobalVariables.SelectedListItem]);
        foodNameEditBox.Text = FoodRelated.FoodNameList [0];
        foodNameEditBox.TextAlign = center;
        servingSizeEditBox.Text = FoodRelated.ServingSizeList [0].ToString ();
        servingSizeEditBox.TextAlign = center;
        definerEditBox.Text = FoodRelated.DefinersList [0];
        definerEditBox.TextAlign = center;
        caloriesPerServingEditBox.Text = FoodRelated.CaloriesPerServingList [0].ToString ();
        caloriesPerServingEditBox.TextAlign = center;
        Validation.checkCurrentRadioButton (timeRadioButton, calorieRadioButton, caloriesLabel);
        manualCalorieEditBox.Value = decimal.Parse (FoodRelated.Calories.ToString ());
    }

    public static void dumpFoodPropertiesList (TextBox foodNameEditBox, NumericUpDown servingSizeEditBox,
                                               NumericUpDown caloriesPerServingEditBox, TextBox definerEditBox)
    {
        foodNameEditBox.Clear ();
        servingSizeEditBox.Value = 0;
        caloriesPerServingEditBox.Value = 0;
        definerEditBox.Clear ();
    }

    public static void refresh_foodList (ListBox foodList)
    {
        FoodRelated.FoodNameList.Clear ();
        FoodRelated.ServingSizeList.Clear ();
        FoodRelated.CaloriesPerServingList.Clear ();
        FoodRelated.DefinersList.Clear ();
        Storage.readFoodTable ("Text Files\\", "food.table");
        foodList.DataSource = null;
        foodList.Items.Clear ();
        foodList.DataSource = FoodRelated.FoodNameList.Values.ToList ();
        Storage.writeFoodTable ("Text Files\\", "food.table", new string[] { 
            null,
            null,
            null,
            null
        });
    }

    public static void foodPropertiesSwitch (ListBox foodList, TextBox foodNameEditBox, NumericUpDown servingSizeEditBox,
                                             NumericUpDown caloriesPerServingEditBox, TextBox definerEditBox, CheckBox newItemCheckbox)
    {
        if (string.IsNullOrEmpty (foodNameEditBox.Text)) {
            ErrorHandler.errorMessageBox ("Please set a food name value!", foodNameEditBox, 0, true);
            return;
        }
        if (servingSizeEditBox.Value <= 0) {
            ErrorHandler.errorMessageBox ("Please set a serving size value!", servingSizeEditBox, 0, true);
            return;
        }
        if (caloriesPerServingEditBox.Value <= 0) {
            ErrorHandler.errorMessageBox ("Please set a calories per serving value!", caloriesPerServingEditBox, 0, true);
            return;
        }
        if (string.IsNullOrEmpty (definerEditBox.Text)) {
            ErrorHandler.errorMessageBox ("Please set a definer value!", definerEditBox, 0, true);
            return;
        }
        if (Equals (GlobalVariables.AddItem, false)) {
            FoodRelated.FoodNameList [GlobalVariables.SelectedListItem] = foodNameEditBox.Text;
            FoodRelated.ServingSizeList [GlobalVariables.SelectedListItem] = float.Parse (servingSizeEditBox.Text);
            FoodRelated.CaloriesPerServingList [GlobalVariables.SelectedListItem] = float.Parse (caloriesPerServingEditBox.Text);
            FoodRelated.DefinersList [GlobalVariables.SelectedListItem] = definerEditBox.Text;
            Storage.writeFoodTable ("Text Files\\", "food.table", new string[] {
                null,
                null,
                null,
                null
            }
            );
        } else {
            Storage.writeFoodTable ("Text Files\\", "food.table", new [] {
                foodNameEditBox.Text,
                servingSizeEditBox.Text,
                caloriesPerServingEditBox.Text,
                definerEditBox.Text
            }
            );
            newItemCheckbox.Checked = false;
        }
        refresh_foodList (foodList);
    }

    public static float modifyCalories (NumericUpDown userServingInputTextBox, bool add)
    {
        int hour = DateTime.Now.Hour;
        string amPMDefiner = DateTime.Now.ToString ("tt");
        Storage.readRegistry (GlobalVariables.RegistryAppenedValue, GlobalVariables.registryMainValue);
        float tempFloat = FoodRelated.CaloriesPerServingList [GlobalVariables.SelectedListItem] * float.Parse (userServingInputTextBox.Text) / FoodRelated.ServingSizeList [GlobalVariables.SelectedListItem];
        if (hour > 12 && hour < 4 && amPMDefiner.Equals ("am", StringComparison.CurrentCultureIgnoreCase)) {
            float midSnackPenalty = tempFloat / 10;
            if (midSnackPenalty <= 10) {
                midSnackPenalty = 10;
            }
            string appliedSwitch = Equals (add, false) ? "applied" : "subtracted";
            DialogResult dialogResult = MessageBox.Show (string.Format ("A midnight snacking penalty of {0} will be {1} if you continue.", midSnackPenalty, appliedSwitch), "Midnight Snacking Penalty.", MessageBoxButtons.OKCancel, MessageBoxIcon.Information, MessageBoxDefaultButton.Button2);
            switch (dialogResult) {
            case DialogResult.OK:
                if (Equals (add, false)) {
                    return tempFloat + midSnackPenalty;
                }
                return tempFloat - midSnackPenalty;
            default:
                return 0;
            }
        }
        return tempFloat;
    }

    public static void find (int offset, string stringToFind, string stringToAvoid, bool exactSearch, ListBox foodList)
    {
        for (int i = offset; i < foodList.Items.Count; i++) {
            const bool b = true;
            if (Equals (exactSearch, b)) {
                if (Equals (foodList.Items [i].ToString ().Equals (stringToFind, StringComparison.CurrentCultureIgnoreCase), b) &&
                    !foodList.Items [i].ToString ().Equals (stringToAvoid, StringComparison.CurrentCultureIgnoreCase)) {
                    foodList.SelectedIndex = i;
                    break;
                }
            } else {
                if (Equals (foodList.Items [i].ToString ().Contains (stringToFind, StringComparison.CurrentCultureIgnoreCase), b) &&
                    !foodList.Items [i].ToString ().Equals (stringToAvoid, StringComparison.CurrentCultureIgnoreCase)) {
                    foodList.SelectedIndex = i;
                    break;
                }
            }
        }
    }

}

public static class Storage
{

    //      Functions that relate to storage

    public static void readFoodTable (string directory, string file)
    {
        int position = 0;
        String line;
        if (!File.Exists (directory + "food table.txt")) {
            using (StreamReader sr = new StreamReader (directory + file)) {
                int number = 0;
                while (!string.IsNullOrEmpty ((line = sr.ReadLine ()))) {
                    if (line.Contains ("-", StringComparison.CurrentCultureIgnoreCase)) {
                        position++;
                        number = 0;
                    } else {
                        switch (number) {
                        case 0:
                            FoodRelated.FoodNameList.Add (position, line);
                            break;
                        case 1:
                            FoodRelated.ServingSizeList.Add (position, float.Parse (line));
                            break;
                        case 2:
                            FoodRelated.CaloriesPerServingList.Add (position, float.Parse (line));
                            break;
                        case 3:
                            FoodRelated.DefinersList.Add (position, line);
                            break;
                        }
                        number++;
                    }
                }
                sr.Close ();
            }
        } else {
            using (StreamReader sr = new StreamReader (directory + "food table.txt")) {
                int[] number = {
                    0,
                    0,
                    0,
                    0
                };
                while (!Equals ((line = sr.ReadLine ()), null)) {
                    if (line.Contains ("-", StringComparison.CurrentCultureIgnoreCase)) {
                        position++;
                    } else {
                        switch (position) {
                        case 0:
                            FoodRelated.FoodNameList.Add (number [position], line);
                            break;
                        case 1:
                            FoodRelated.ServingSizeList.Add (number [position], float.Parse (line));
                            break;
                        case 2:
                            FoodRelated.CaloriesPerServingList.Add (number [position], float.Parse (line));
                            break;
                        case 3:
                            FoodRelated.DefinersList.Add (number [position], line);
                            break;
                        }
                        number [position]++;
                    }
                }
                sr.Close ();
            }
        }
    }

    public static void writeFoodTable (string directory, string file, string[] addString)
    {
        if (File.Exists (string.Format ("{0}food.table", directory))) {
            File.Delete (string.Format ("{0}food.table", directory));
        }
        string finalstring = null;
        const string seperator = "-------------------------------------------------------------------------\n";
        for (int i = 0; i < FoodRelated.FoodNameList.Count; i++) {
            finalstring = finalstring + FoodRelated.FoodNameList [i] + "\n";
            finalstring = finalstring + FoodRelated.ServingSizeList [i] + "\n";
            finalstring = finalstring + FoodRelated.CaloriesPerServingList [i] + "\n";
            finalstring = finalstring + FoodRelated.DefinersList [i] + "\n";
            finalstring = finalstring + seperator;
        }
        if (!string.IsNullOrEmpty (addString [0])) {
            finalstring = string.Format ("{0}{1}\n", finalstring, addString [0]);
            finalstring = string.Format ("{0}{1}\n", finalstring, addString [1]);
            finalstring = string.Format ("{0}{1}\n", finalstring, addString [2]);
            finalstring = string.Format ("{0}{1}\n", finalstring, addString [3]);
            finalstring = string.Format ("{0}{1}", finalstring, seperator);
        }
        File.WriteAllText (directory + file, finalstring);
    }

    public static void readRegistry (string appendedRegistryValue, string registyValue)
    {
        using (RegistryKey tempKey = Registry.LocalMachine.OpenSubKey (appendedRegistryValue + registyValue, true)) {
            string temp = tempKey.GetValue ("Calories Left for the Day").ToString ();
            FoodRelated.Calories = float.Parse (temp);
            DateTime.TryParseExact (tempKey.GetValue ("Last Used Date").ToString (), new [] { "yyyy MMMMM dd hh:mm:ss tt" }, CultureInfo.InvariantCulture, DateTimeStyles.None, out GlobalVariables.dateReset);
        }
    }

    public static void writeRegistry (string appendedRegistryValue, string registyValue, bool reset)
    {
        const bool b = true;
        if (Equals (reset, false)) {
            using (RegistryKey tempKey = Registry.LocalMachine.OpenSubKey (appendedRegistryValue + registyValue, b)) {
                tempKey.SetValue ("Calories Left for the Day", FoodRelated.Calories.ToString ());
            }
        } else {
            using (RegistryKey tempKey = Registry.LocalMachine.OpenSubKey (GlobalVariables.RegistryAppenedValue + GlobalVariables.registryMainValue, b)) {
                tempKey.SetValue ("Calories Left for the Day", FoodRelated.TotalCaloriesPerDay.ToString (), RegistryValueKind.String);
                tempKey.SetValue ("Last Used Date", GlobalVariables.NowDate.AddDays (1).ToString ("yyyy MMMMM dd hh:mm:ss tt"), RegistryValueKind.String);
            }
        }
    }

    public static bool checkRegistryValues (string appendedRegistryValue, string registyValue)
    {
        if (!Equals (Registry.LocalMachine.OpenSubKey (appendedRegistryValue + registyValue), null))
            return false;
        Registry.LocalMachine.CreateSubKey (appendedRegistryValue + registyValue);
        using (RegistryKey tempKey = Registry.LocalMachine.OpenSubKey (appendedRegistryValue + registyValue, true)) {
            tempKey.SetValue ("Calories Left for the Day", FoodRelated.TotalCaloriesPerDay.ToString (), RegistryValueKind.String);
            tempKey.SetValue ("Last Used Date", GlobalVariables.NowDate.AddDays (1).ToString ("yyyy MMMMM dd hh:mm:ss tt"), RegistryValueKind.String);
        }
        return true;
    }
}
}
11 голосов | спросил anonymousman21 16 TueEurope/Moscow2014-12-16T16:10:40+03:00Europe/Moscow12bEurope/MoscowTue, 16 Dec 2014 16:10:40 +0300 2014, 16:10:40

2 ответа


10

Добро пожаловать на обзор кода!

По соглашению ваше пространство имен не должно содержать символов подчеркивания, вы должны разделить их на ., если это необходимо (что не является в вашем случае я думаю)

Weight_Watching_Program -> WeightWatchingProgram

У ваших членов нет модификатора доступности, по умолчанию это private, но мне нравится верить, что читать легче когда это всегда так, чтобы другим разработчикам не приходилось думать о том, забыли ли вы это или нет. (Вы можете сказать, что вы единственный в своем проекте, я не знаю, хотя вы всегда должны кодировать идею о том, что кто-то еще может просмотреть ваш код, как ... Прямо сейчас!)

Все ваши «классы» объявляются как struct на данный момент, и вы не должны этого делать. Структуры предназначены для легких (неизменяемых) объектов. Если вам нужна дополнительная информация, прочитайте следующее: http://msdn.microsoft.com /en-us/library/0taef578.aspx

Ваши свойства объявлены следующим образом:

static Dictionary<int, string> definersList = new Dictionary<int, string> ();

public static Dictionary<int, string> DefinersList {
    get {
        return definersList;
    }
    set {
        definersList = value;
    }
}

В C # вы можете использовать авто-свойства, чтобы сделать его немного короче. Вот так:

public static Dictionary<int, string> DefinersList { get; set; }

Но тогда у вас есть проблема, вы никогда не устанавливаете свою собственность. Помните, что при «своем» способе вы создаете новый экземпляр Dictionary<int,string>, когда вы объявляете свою переменную.

Чтобы решить эту проблему, вы должны иметь constructor в своем классе, который задает ваши свойства. * Обратите внимание, что это не сработает, если вы продолжаете использовать struct, поскольку вы не можете объявить пустой конструктор.

public FoodRelated()
{
    DefinersList = new = new Dictionary<int, string> ();
    //Do this for all your properties
}

По-моему, этот метод имеет то преимущество, что сохраняя все ваши объявления в одном и том же месте (конструктор), а не распространяя их по всему вашему коду!

Ваш static readonly string должен быть const string он никогда не должен меняться. Этот ответ StackOverflow содержит некоторую полезную информацию: https://stackoverflow.com/questions/755685/с-статического чтения-против-Const

Кроме того, вам легче читать код, если вы поместите все члены в верхней части своего класса, а затем свойства вместо их смешивания. Этот SO ответ, поскольку он был закрыт, поэтому я не буду повторять все это: https://stackoverflow.com/questions/603758/whats-the-best-way-to-layout-ac-sharp-class .

В соглашении C # вы должны поместить скобки в новую строку. Мое объяснение может быть не лучшим, вот пример:

if (true){ //not cool
}

if(true) //Pretty cool
{
}

Вы написали слишком много кода здесь: Equals (deleteSelectedFoodItemButton.Enabled, true) a bool по умолчанию ... a bool! Учтите, что Equals возвращает true, если deleteSelectedFoodItemButton.Enabled equals true, вы можете сократить его до ---- +: = 21 = + ----.

Но подождите, есть еще! Поскольку deleteSelectedFoodItemButton.Enabled == true сам является логическим, вы можете сократить его до: deleteSelectedFoodItemButton.Enabled. (Извините за плохой читабельность этого параграфа!)

deleteSelectedFoodItemButton.Enabled

затем становится:

if (Equals (deleteSelectedFoodItemButton.Enabled, true) && foodList.Items.Count <= 0)

Вы можете сделать то же самое с помощью if (deleteSelectedFoodItemButton.Enabled && foodList.Items.Count <= 0) с помощью Equals (deleteSelectedFoodItemButton.Enabled, true).

!

становится:

if (Equals (deleteSelectedFoodItemButton.Enabled, false))

В этой же идее if (!deleteSelectedFoodItemButton.Enabled) можно изменить на

if (Equals (labelToChange, null))

В вашем коде вы часто разделяете вызов метода из if (labelToChange == null) с пробелом, вам не нужно это делать, для этого просто нужны пробелы. Это то, что яозначает:

()

Я вижу, что вы используете Validation.checkCurrentRadioButton /*space here that should be removed*/ (timeRadioButton, calorieRadioButton, caloriesLabel); , но считаете ли вы, что если бы я вводил только пробелы в ваш код, он прошел бы это подтверждение ввода. Если это не желаемое поведение, вы можете использовать String.IsNullOrEmpty.

Наконец, вы не должны ставить все String.IsNullOrWhiteSpace в static, который не является статическим. Но в этой ситуации я считаю, что большая часть вашего кода не должна быть статичной. Когда вы помещаете что-то class, спросите себя, нужно ли его использовать всеми экземплярами вашего static, в этой ситуации ваш код class - это весь контент вашего класса, поэтому вы не следует устанавливать это в static. Вместо этого вы должны объявлять экземпляры своего класса.

ответил IEatBagels 16 TueEurope/Moscow2014-12-16T16:46:43+03:00Europe/Moscow12bEurope/MoscowTue, 16 Dec 2014 16:46:43 +0300 2014, 16:46:43
6
  • structs следует использовать, если объект, который он представляет, является легким и неизменным, поэтому вам лучше использовать классы.

  • методы должны быть названы с использованием оболочки PascalCase, см. рекомендации по именованию
    Пример: public static void checkDateValidity(DateTime dateToCompareTo, DateTime dateToCheck, bool firstProgramUse)

  • с помощью инструкции using очень хорошо. Если вы используете его с помощью StreamReader, вызов Dispose(), который выполняется с помощью using вызывает Close() внутренне.

  • использование switch ..case - это хорошо, но если его можно изменить на простой if..else используйте более поздний

        switch (dialogResult) {
        case DialogResult.OK:
            if (Equals (add, false)) {
                return tempFloat + midSnackPenalty;
            }
            return tempFloat - midSnackPenalty;
        default:
            return 0;
        }

может быть

    if (dialogResult != DialogResult.OK){
        return 0;
    }

    if (Equals (add, false)) 
    {
        return tempFloat + midSnackPenalty;
    }

    return tempFloat - midSnackPenalty;
  • ваше отступление как-то выключено (см. выше). Использование правильного отступа увеличит читаемость (см. Мой пример выше).

  • вы должны соответствовать стилю, который вы используете. Если вы не используете фигурные скобки {} для одиночного if, что было бы плохой игрой ИМХО, вы должны придерживаться этого. Но лучше используйте их, потому что это делает ваш код менее ошибочным.

  • a ListBox может содержать элементы или не может. Поэтому проверка Count для <= 0 бесплодна , Лучше проверить Count != 0

ответил Heslacher 16 TueEurope/Moscow2014-12-16T16:54:28+03:00Europe/Moscow12bEurope/MoscowTue, 16 Dec 2014 16:54:28 +0300 2014, 16:54:28

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132