抽象クラスの特性
抽象クラスは抽象メソッドを含み、そのメソッドは実装を持たず派生クラスでオーバーライドされる必要があります。インスタンス化は不可能です。
public abstract class Geometry {
public abstract double CalculatePerimeter();
}
public class Rectangle : Geometry {
public double Width { get; set; }
public double Height { get; set; }
public override double CalculatePerimeter() => 2 * (Width + Height);
}
virtual修飾子の活用
virtual修飾子を付与したメソッドは派生クラスで上書き可能です。実行時の型に基づいて最適な実装が呼び出されます。
public class Transport {
public virtual void Move() {
Console.WriteLine("移動中");
}
}
public class Aircraft : Transport {
public override void Move() {
Console.WriteLine("飛行中");
}
}
sealedクラスの制約
sealed修飾子を付与したクラスは継承が禁止されます。クラスの拡張を防ぐ目的で使用されます。
sealed class SecureComponent {
public void Execute() {
// セキュリティ処理
}
}
// エラー: sealedクラスを継承できません
// class Extended : SecureComponent { }
静的クラスの設計原則
静的クラスはインスタンス化できず、すべてのメンバーが静的である必要があります。コンパイラが自動的にsealed属性を付与し、インスタンスメンバーの追加を防ぎます。
public static class MathOperations {
public static int Multiply(int a, int b) => a * b;
public static double CalculateArea(double radius) => Math.PI * radius * radius;
}
文字列処理の最適化戦略
String型は不変性のため、変更時に新規メモリ領域が生成されます。StringBuilderはバッファ再利用により効率的に処理できます。
// 不効率な文字列結合
string combined = "";
for (int i = 0; i < 5000; i++) {
combined += i.ToString(); // 新規オブジェクト生成
}
// 効率的な処理
StringBuilder builder = new StringBuilder(10000);
for (int i = 0; i < 5000; i++) {
builder.Append(i.ToString());
}
string result = builder.ToString();
参照型と値型の違い
クラスは参照型、構造体は値型です。構造体は継承をサポートせず、デフォルトコンストラクタが自動生成されます。
struct Position {
public int X;
public int Y;
}
class Location {
public int X;
public int Y;
}
// 値型の挙動
Position p1 = new Position { X = 5, Y = 10 };
Position p2 = p1;
p2.X = 20; // p1には影響なし
// 参照型の挙動
Location l1 = new Location { X = 5, Y = 10 };
Location l2 = l1;
l2.X = 20; // l1のXも20に変更
IDisposableによるリソース管理
usingブロック内でIDisposableを実装したオブジェクトを扱うと、ブロック終了時に自動的にDisposeが呼び出されます。
using (var dbConnection = new DatabaseConnection()) {
dbConnection.Connect();
// データ操作
} // 自動でDispose実行
ジェネリックコレクションの選択
List<T>は型安全なジェネリックコレクションで、ArrayListは非ジェネリックです。型キャストのオーバーヘッドがなくパフォーマンスが向上します。
List<string> names = new List<string> { "Alice", "Bob" };
// ArrayListの例(非推奨)
ArrayList mixedList = new ArrayList { 1, "two", 3.0 };
ハッシュベースコレクションの比較
Dictionary<TKey, TValue>はジェネリックで型安全、HashTableは非ジェネリックです。Dictionaryはパフォーマンス面で優れています。
Dictionary<string, int> scores = new Dictionary<string, int> {
{ "math", 95 },
{ "science", 87 }
};
// HashTableの例
Hashtable scoresTable = new Hashtable {
{ "math", 95 },
{ "science", 87 }
};
C# 8.0の新機能実装例
範囲演算子やスイッチ式など、C# 8.0の新機能を活用したコード例です。
// 範囲演算子
int[] data = { 10, 20, 30, 40, 50 };
var subset = data[1..3]; // { 20, 30 }
// スイッチ式
string GetStatus(int code) => code switch {
1 => "Active",
2 => "Inactive",
_ => "Unknown"
};
コレクションの重複排除
Distinctメソッドを使用してコレクションの重複要素を効率的に排除できます。
List<int> values = new List<int> { 5, 3, 5, 7, 3 };
var uniqueValues = values.Distinct().ToList(); // { 5, 3, 7 }