チュートリアル

C#基礎:クラス

CSharp入門クラスオブジェクト指向
広告エリア

クラスの定義

public class Person
{
    // フィールド
    private string _name;
    private int _age;

    // コンストラクタ
    public Person(string name, int age)
    {
        _name = name;
        _age = age;
    }

    // プロパティ
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }

    public int Age
    {
        get { return _age; }
        set
        {
            if (value >= 0)
                _age = value;
        }
    }

    // メソッド
    public void Greet()
    {
        Console.WriteLine($"こんにちは、{_name}です");
    }
}

// 使用
var person = new Person("太郎", 25);
person.Greet();
Console.WriteLine(person.Name);

プロパティ

自動実装プロパティ

public class User
{
    // 自動実装プロパティ
    public string Name { get; set; }
    public int Age { get; set; }

    // 読み取り専用
    public DateTime CreatedAt { get; } = DateTime.Now;

    // init-only(初期化時のみ設定可能)
    public string Id { get; init; }

    // プライベートセッター
    public int Count { get; private set; }

    public void Increment() => Count++;
}

// オブジェクト初期化子
var user = new User
{
    Name = "太郎",
    Age = 25,
    Id = "user-001"
};

計算プロパティ

public class Rectangle
{
    public double Width { get; set; }
    public double Height { get; set; }

    // 計算プロパティ(式本体)
    public double Area => Width * Height;
    public double Perimeter => 2 * (Width + Height);
}

required プロパティ(C# 11)

public class Product
{
    public required string Name { get; set; }
    public required decimal Price { get; set; }
    public string? Description { get; set; }
}

// 必須プロパティは初期化必須
var product = new Product
{
    Name = "本",
    Price = 1500
};

コンストラクタ

複数のコンストラクタ

public class Book
{
    public string Title { get; }
    public string Author { get; }
    public int Price { get; }

    public Book(string title) : this(title, "不明", 0)
    {
    }

    public Book(string title, string author) : this(title, author, 0)
    {
    }

    public Book(string title, string author, int price)
    {
        Title = title;
        Author = author;
        Price = price;
    }
}

プライマリコンストラクタ(C# 12)

public class Person(string name, int age)
{
    public string Name { get; } = name;
    public int Age { get; } = age;

    public void Greet() => Console.WriteLine($"こんにちは、{name}です");
}

static メンバー

public class Counter
{
    private static int _count = 0;
    public int Id { get; }

    public Counter()
    {
        _count++;
        Id = _count;
    }

    public static int GetCount() => _count;
}

var c1 = new Counter();
var c2 = new Counter();
Console.WriteLine(Counter.GetCount());  // 2

静的クラス

public static class MathUtils
{
    public const double PI = 3.14159;

    public static int Add(int a, int b) => a + b;
    public static int Max(int a, int b) => a > b ? a : b;
}

// インスタンス化不可、静的メンバーのみ
int sum = MathUtils.Add(3, 5);

record

不変データ型を簡潔に定義します。

// record(参照型)
public record Person(string Name, int Age);

var person1 = new Person("太郎", 25);
var person2 = new Person("太郎", 25);

Console.WriteLine(person1 == person2);  // true(値で比較)
Console.WriteLine(person1);  // Person { Name = 太郎, Age = 25 }

// with式でコピー
var person3 = person1 with { Age = 26 };

// 分解
var (name, age) = person1;

record class と record struct

// record class(参照型、デフォルト)
public record class UserRecord(string Name, int Age);

// record struct(値型)
public record struct Point(int X, int Y);

// 読み取り専用record struct
public readonly record struct ImmutablePoint(int X, int Y);

struct(構造体)

値型の軽量なデータ構造です。

public struct Point
{
    public int X { get; set; }
    public int Y { get; set; }

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    public double DistanceTo(Point other)
    {
        return Math.Sqrt(Math.Pow(other.X - X, 2) + Math.Pow(other.Y - Y, 2));
    }
}

Point p1 = new(0, 0);
Point p2 = new(3, 4);
Console.WriteLine(p1.DistanceTo(p2));  // 5

readonly struct

public readonly struct ImmutablePoint
{
    public int X { get; }
    public int Y { get; }

    public ImmutablePoint(int x, int y)
    {
        X = x;
        Y = y;
    }
}

部分クラス

// File1.cs
public partial class Customer
{
    public string Name { get; set; }
    public string Email { get; set; }
}

// File2.cs(自動生成コードなど)
public partial class Customer
{
    public void Validate()
    {
        // バリデーション処理
    }
}

sealed クラス

継承を禁止します。

public sealed class FinalClass
{
    public void DoSomething() { }
}

// public class Derived : FinalClass { }  // エラー

実践例:銀行口座

public class BankAccount
{
    private static int _nextAccountNumber = 1000;

    public int AccountNumber { get; }
    public string OwnerName { get; }
    public decimal Balance { get; private set; }

    public BankAccount(string ownerName, decimal initialBalance = 0)
    {
        AccountNumber = _nextAccountNumber++;
        OwnerName = ownerName;
        Balance = initialBalance;
    }

    public void Deposit(decimal amount)
    {
        if (amount <= 0)
            throw new ArgumentException("金額は正の値である必要があります");

        Balance += amount;
        Console.WriteLine($"{amount:C}を入金しました。残高: {Balance:C}");
    }

    public bool Withdraw(decimal amount)
    {
        if (amount <= 0)
            throw new ArgumentException("金額は正の値である必要があります");

        if (amount > Balance)
        {
            Console.WriteLine("残高不足です");
            return false;
        }

        Balance -= amount;
        Console.WriteLine($"{amount:C}を出金しました。残高: {Balance:C}");
        return true;
    }

    public override string ToString()
        => $"口座番号: {AccountNumber}, 名義: {OwnerName}, 残高: {Balance:C}";
}

// 使用
var account = new BankAccount("山田太郎", 10000);
account.Deposit(5000);
account.Withdraw(3000);
Console.WriteLine(account);

実践例:設定クラス(シングルトン)

public sealed class AppConfig
{
    private static readonly Lazy<AppConfig> _instance =
        new(() => new AppConfig());

    public static AppConfig Instance => _instance.Value;

    public string DatabaseConnection { get; set; } = "";
    public bool DebugMode { get; set; }
    public int MaxRetries { get; set; } = 3;

    private AppConfig() { }
}

// 使用
AppConfig.Instance.DebugMode = true;
Console.WriteLine(AppConfig.Instance.MaxRetries);

まとめ

  • クラスはフィールド、プロパティ、コンストラクタ、メソッドで構成
  • 自動実装プロパティで簡潔に記述
  • initで初期化時のみ設定可能なプロパティ
  • requiredで必須プロパティ
  • recordで不変データ型を簡潔に定義
  • structで軽量な値型を定義
  • staticでクラスレベルのメンバー
  • sealedで継承を禁止

次回は継承とインターフェースについて学びます。

広告エリア