C#: основы языка и приложение с интерфейсом

Синтаксис C#, свойства и автосвойства, коллекции и LINQ, обработка исключений, создание оконного приложения на Windows Forms и работа с базой данных.

C# выбирают для курсовых, где нужно быстро получить работающее приложение с оконным интерфейсом. Visual Studio позволяет собрать форму мышью, а на защите наглядная программа выигрывает у консольной.

Класс и свойства

public class Product
{
    // Автосвойство — компилятор сам создаёт скрытое поле
    public string Name { get; set; }
    public int Quantity { get; set; }

    private decimal price;
    public decimal Price                    // свойство с проверкой
    {
        get => price;
        set
        {
            if (value < 0)
                throw new ArgumentException("Цена не может быть отрицательной");
            price = value;
        }
    }

    public decimal Total => Price * Quantity;   // вычисляемое свойство

    public Product(string name, decimal price, int quantity)
    {
        Name = name;
        Price = price;
        Quantity = quantity;
    }

    public override string ToString() => $"{Name}: {Price:C} × {Quantity} = {Total:C}";
}
Свойства — визитная карточка C#: снаружи выглядят как поля, внутри работают как методы. Поэтому проверку значения можно добавить позже, не меняя код, который этим свойством пользуется.

Коллекции и LINQ

using System;
using System.Collections.Generic;
using System.Linq;

var products = new List<Product>
{
    new Product("Резистор", 5.50m, 100),
    new Product("Конденсатор", 12.00m, 50),
    new Product("Транзистор", 45.00m, 20)
};

// Фильтрация и сортировка
var expensive = products
    .Where(p => p.Price > 10)
    .OrderByDescending(p => p.Total)
    .ToList();

// Агрегация
decimal sum = products.Sum(p => p.Total);
decimal avg = products.Average(p => p.Price);
var maxItem = products.MaxBy(p => p.Total);

// Группировка
var groups = products
    .GroupBy(p => p.Price > 10 ? "дорогие" : "дешёвые")
    .Select(g => new { Категория = g.Key, Сумма = g.Sum(p => p.Total) });

foreach (var g in groups)
    Console.WriteLine($"{g.Категория}: {g.Сумма:C}");

// Словарь
var byName = products.ToDictionary(p => p.Name, p => p.Quantity);
if (byName.TryGetValue("Резистор", out int qty))
    Console.WriteLine($"Резисторов на складе: {qty}");
Метод LINQЧто делает
WhereФильтрует по условию
SelectПреобразует каждый элемент
OrderBy / ThenByСортирует по одному и следующему критерию
GroupByГруппирует по ключу
Sum / Average / CountАгрегирует
Any / AllПроверяет наличие хотя бы одного / всех
FirstOrDefaultПервый подходящий или значение по умолчанию
JoinСоединяет две коллекции по ключу

LINQ читается как SQL и заменяет циклы с ветвлениями одной цепочкой вызовов. В отчёте это стоит подчеркнуть: код короче и его труднее сломать при правках.

Оконное приложение на Windows Forms

public partial class MainForm : Form
{
    private readonly List<Product> products = new();

    public MainForm()
    {
        InitializeComponent();
        dataGridView1.AutoGenerateColumns = true;
    }

    private void btnAdd_Click(object sender, EventArgs e)
    {
        try
        {
            var p = new Product(
                txtName.Text.Trim(),
                decimal.Parse(txtPrice.Text),
                int.Parse(txtQty.Text));

            products.Add(p);
            RefreshGrid();
            ClearInputs();
        }
        catch (FormatException)
        {
            MessageBox.Show("Цена и количество должны быть числами",
                            "Ошибка ввода", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }
        catch (ArgumentException ex)
        {
            MessageBox.Show(ex.Message, "Ошибка");
        }
    }

    private void RefreshGrid()
    {
        dataGridView1.DataSource = null;
        dataGridView1.DataSource = products;
        lblTotal.Text = $"Итого: {products.Sum(p => p.Total):C}";
    }

    private void ClearInputs()
    {
        txtName.Clear(); txtPrice.Clear(); txtQty.Clear();
        txtName.Focus();
    }
}
Обработка FormatException при разборе введённого текста — обязательный минимум. Программа, падающая от буквы в поле цены, снижает оценку сильнее, чем скромный интерфейс.

Работа с базой данных

using Microsoft.Data.SqlClient;

string connStr = @"Server=(localdb)\MSSQLLocalDB;Database=Warehouse;Trusted_Connection=True;";

using var conn = new SqlConnection(connStr);
conn.Open();

// Параметризованный запрос — защита от SQL-инъекций
const string sql = "SELECT Name, Price, Quantity FROM Products WHERE Price > @minPrice";
using var cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("@minPrice", 10m);

using var reader = cmd.ExecuteReader();
while (reader.Read())
{
    Console.WriteLine($"{reader.GetString(0)} — {reader.GetDecimal(1):C}");
}

Параметры вместо склейки строк — не только защита от инъекций, но и обязательный пункт в разделе безопасности курсовой. Конкатенация запроса из пользовательского ввода почти всегда получает замечание.

Полезные конструкции

// Проверка на null и значение по умолчанию
string name = input?.Trim() ?? "без названия";

// Сопоставление с образцом
string category = price switch
{
    < 100    => "дешёвый",
    < 1000   => "средний",
    _        => "дорогой"
};

// Кортежи для возврата двух значений
(decimal min, decimal max) GetRange(List<Product> items)
    => (items.Min(p => p.Price), items.Max(p => p.Price));

// Асинхронность, чтобы интерфейс не подвисал
private async void btnLoad_Click(object sender, EventArgs e)
{
    btnLoad.Enabled = false;
    var data = await Task.Run(() => LoadFromDatabase());
    RefreshGrid();
    btnLoad.Enabled = true;
}

Структура курсовой по C#

  1. Постановка задачи и функциональные требования списком.
  2. Диаграмма классов и описание назначения каждого класса.
  3. Схема базы данных, если она есть, с обоснованием нормальной формы.
  4. Описание интерфейса со снимками экрана всех форм.
  5. Ключевые фрагменты кода в тексте, полный листинг — в приложение.
  6. Таблица тестирования: действие, ожидаемый результат, фактический.
  7. Руководство пользователя на одну-две страницы.

Частые вопросы

Windows Forms или WPF для курсовой?

Forms проще и быстрее: перетащили элементы, написали обработчики. WPF даёт гибкое оформление и разделение логики через MVVM, но требует освоить XAML и привязки. Если задача — успеть к сроку, берите Forms.

Чем отличается свойство от поля?

Поле хранит данные, свойство управляет доступом к ним через методы get и set. Снаружи синтаксис одинаков, поэтому поле всегда можно заменить свойством, не переписывая вызывающий код.

Зачем async, если программа работает?

Долгая операция в обработчике кнопки замораживает окно: интерфейс не отвечает, Windows помечает его как «не отвечает». async выносит работу в отдельный поток и возвращает отзывчивость.

Читайте также

Сделаем работу по этой теме

Опишите задачу — ответим в течение 15 минут в личных сообщениях ВКонтакте, назовём срок и цену. Предоплаты за оценку нет.

  • Оценка заявки бесплатно
  • Правки по замечаниям преподавателя
  • Работы по всем техническим и IT-дисциплинам

Нажимая кнопку, вы соглашаетесь на обработку указанных данных для ответа на заявку.