.NET ヘルプ

C# 構造体 vs クラス (開発者のための仕組み)

公開済み 2024年3月6日
共有:

C#において、構造体(struct)とクラス(class)はいずれもデータを整理および格納するための基本的な構成要素ですが、異なるシナリオに適した特有の特徴を持っています。 以下に翻訳しました:

違いを理解するC# 構造体とクラスC#アプリケーションを設計する際に情報に基づいた意思決定を行うためには、非常に重要です。

この記事では、構造体とクラスの主要な違いを探り、その使用例、メモリ管理、およびパフォーマンスへの影響について論じます。 また、構造体とクラスの使用方法についても説明します。C#のためのIronPDFPDFファイル作成用。

構造体とクラスの概要

1.1. クラス(参照型)

参照型: C#のクラスはヒープ上に存在する参照型であり、クラスのインスタンスが作成されると、そのオブジェクトへの参照がメモリに格納されます。

ヒープ割り当て: クラスインスタンスはヒープメモリ割り当てでメモリが割り当てられ、サイズに柔軟性を持たせるとともに、オブジェクトをコードの異なる部分で共有することができます。

デフォルトコンストラクタ: クラスはデフォルトコンストラクタを持つことができ、明示的に定義されていない場合、自動的に提供されます。

継承: クラスは継承をサポートしており、共有する特性を持つ派生クラスを作成することができます。

using System;
// Define a class
public class MyClass
{
    // Fields (data members)
    public int MyField;
    // Constructor
    public MyClass(int value)
    {
        MyField = value;
    }
    // Method
    public void Display()
    {
        Console.WriteLine($"Value in MyClass: {MyField}");
    }
}
class Program
{
    static void Main()
    {
        // Create an instance of the class
        MyClass myClassInstance = new MyClass(10);
        // Access field and call method
        myClassInstance.Display();
        // Classes are reference types, so myClassInstance refers to the same object in memory
        MyClass anotherInstance = myClassInstance;
        anotherInstance.MyField = 20;
        // Both instances refer to the same object, so the change is reflected in both
        myClassInstance.Display();
        anotherInstance.Display();
    }
}
using System;
// Define a class
public class MyClass
{
    // Fields (data members)
    public int MyField;
    // Constructor
    public MyClass(int value)
    {
        MyField = value;
    }
    // Method
    public void Display()
    {
        Console.WriteLine($"Value in MyClass: {MyField}");
    }
}
class Program
{
    static void Main()
    {
        // Create an instance of the class
        MyClass myClassInstance = new MyClass(10);
        // Access field and call method
        myClassInstance.Display();
        // Classes are reference types, so myClassInstance refers to the same object in memory
        MyClass anotherInstance = myClassInstance;
        anotherInstance.MyField = 20;
        // Both instances refer to the same object, so the change is reflected in both
        myClassInstance.Display();
        anotherInstance.Display();
    }
}
Imports System
' Define a class
Public Class [MyClass]
	' Fields (data members)
	Public MyField As Integer
	' Constructor
	Public Sub New(ByVal value As Integer)
		MyField = value
	End Sub
	' Method
	Public Sub Display()
		Console.WriteLine($"Value in MyClass: {MyField}")
	End Sub
End Class
Friend Class Program
	Shared Sub Main()
		' Create an instance of the class
		Dim myClassInstance As [MyClass] = New [MyClass](10)
		' Access field and call method
		myClassInstance.Display()
		' Classes are reference types, so myClassInstance refers to the same object in memory
		Dim anotherInstance As [MyClass] = myClassInstance
		anotherInstance.MyField = 20
		' Both instances refer to the same object, so the change is reflected in both
		myClassInstance.Display()
		anotherInstance.Display()
	End Sub
End Class
VB   C#

C# 構造体 vs クラス (開発者向けの動作方法): 図1 - 前のコードからのコンソール出力

1.2. 構造体 (値型)

値型について: 構造体(structs)は値型であり、実際のデータは変数が宣言された場所に保存され、プリミティブ型のようにメモリの別の場所には保存されません。これはまた、構造体がNullable<>タグでnullable型として作られない限り、その値型としてnull値を割り当てることができないことを意味します。

スタック割り当て: 構造体のインスタンスはスタック上にメモリが割り当てられます。これにより、割り当てと解放が高速になりますが、サイズとスコープに制限があります。

デフォルトコンストラクタなし: 構造体には、明示的に定義されない限り、デフォルトのコンストラクタはありません。 インスタンス化の際にすべてのフィールドを初期化する必要があります。

継承なし: Structは継承をサポートしていません。 それらは主に軽量なデータ構造のために使用されます。

using System;
// Define a struct
public struct MyStruct
{
    // Fields (data members)
    public int MyField;
    // Constructor
    public MyStruct(int value)
    {
        MyField = value;
    }
    // Method
    public void Display()
    {
        Console.WriteLine($"Value in MyStruct: {MyField}");
    }
}
class Program
{
    static void Main()
    {
        // Create an instance of the struct
        MyStruct myStructInstance = new MyStruct(10);
        // Access field and call method
        myStructInstance.Display();
        // Structs are value types, so myStructInstance is a copy
        MyStruct anotherInstance = myStructInstance;
        anotherInstance.MyField = 20;
        // Changes to anotherInstance do not affect myStructInstance
        myStructInstance.Display();
        anotherInstance.Display();
    }
}
using System;
// Define a struct
public struct MyStruct
{
    // Fields (data members)
    public int MyField;
    // Constructor
    public MyStruct(int value)
    {
        MyField = value;
    }
    // Method
    public void Display()
    {
        Console.WriteLine($"Value in MyStruct: {MyField}");
    }
}
class Program
{
    static void Main()
    {
        // Create an instance of the struct
        MyStruct myStructInstance = new MyStruct(10);
        // Access field and call method
        myStructInstance.Display();
        // Structs are value types, so myStructInstance is a copy
        MyStruct anotherInstance = myStructInstance;
        anotherInstance.MyField = 20;
        // Changes to anotherInstance do not affect myStructInstance
        myStructInstance.Display();
        anotherInstance.Display();
    }
}
Imports System
' Define a struct
Public Structure MyStruct
	' Fields (data members)
	Public MyField As Integer
	' Constructor
	Public Sub New(ByVal value As Integer)
		MyField = value
	End Sub
	' Method
	Public Sub Display()
		Console.WriteLine($"Value in MyStruct: {MyField}")
	End Sub
End Structure
Friend Class Program
	Shared Sub Main()
		' Create an instance of the struct
		Dim myStructInstance As New MyStruct(10)
		' Access field and call method
		myStructInstance.Display()
		' Structs are value types, so myStructInstance is a copy
		Dim anotherInstance As MyStruct = myStructInstance
		anotherInstance.MyField = 20
		' Changes to anotherInstance do not affect myStructInstance
		myStructInstance.Display()
		anotherInstance.Display()
	End Sub
End Class
VB   C#

C# 構造体 vs クラス(開発者向けの仕組み):図2 - 前のコードのコンソール出力

利用事例とガイドライン

2.1. クラスの使用タイミング

複雑な状態と振る舞い: 状態と振る舞いを持つ複雑なデータ構造をモデル化する必要がある場合は、クラスを使用してください。 クラスは、複数のプロパティおよびメソッドを持つ複雑なオブジェクトを表現するのに適しています。

参照セマンティクス: オブジェクトのインスタンスを共有し、コードの異なる部分に変更が反映されるようにしたい場合、クラスが適切な選択です。

2.2. 構造体を使用するタイミング

シンプルなデータ構造: 構造体は、ポイント、長方形、キー-バリューペアなどの小さなデータ構造のような軽量エンティティを表す、よりシンプルなデータ構造に最適です。また、構造体が論理的にプリミティブ型に類似した単一の値を表す場合にも適しています。

値セマンティクス: 値セマンティクスを好み、ヒープ割り当てのオーバーヘッドを避けたい場合、構造体は適しています。

パフォーマンスの考慮事項: パフォーマンスが特に重要なシナリオにおいて、特に小さく頻繁に使用されるオブジェクトに対して、構造体はスタック割り当てによってより効率的になる場合があります。

メモリ割り当ての違い

3.1. クラス

参照カウント: クラスインスタンスのメモリは、ガベージコレクターによる参照カウントで管理されます。 オブジェクトは、それに対する参照がなくなったときにガベージコレクションの対象となります。

メモリリークの可能性: 参照の不適切な取り扱いにより、不要になったオブジェクトが適切に破棄されない場合、メモリリークが発生する可能性があります。

3.2. 構造体

ガベージコレクションなし: 構造体(Structs)は値型であり、異なる方法で管理されているため、ガベージコレクションに依存しません。 スコープから外れたときに自動的に解放されます。

限定メモリオーバーヘッド: 構造体はクラスに比べてメモリオーバーヘッドが低く、メモリ使用量が問題となるシナリオでは効率的です。

パフォーマンスの考慮事項

クラス

間接アクセス: クラスインスタンスは参照を通じてアクセスされるため、追加の間接レベルがあり、若干のパフォーマンスオーバーヘッドを引き起こす可能性があります。

ヒープ割り当て: ヒープ上のメモリの動的割り当ては、オブジェクトの生成および破壊に長い時間がかかる可能性があります。

構造体

直接アクセス: 構造体は直接アクセスされ、余分な間接層が不要です。 これは、小さく頻繁に使用されるオブジェクトのパフォーマンスを向上させる可能性があります。

スタック割り当て: メモリのスタック割り当てにより、structインスタンスの生成と破棄がより迅速になります。

5. IronPDFの紹介

IronPDFの概要:PDF操作のための堅牢なC#ライブラリは、.NETアプリケーション内でのシームレスなPDF生成、操作、レンダリングのために設計されています。 IronPDFを使用すると、開発者はPDFドキュメントを簡単に作成、修正、および操作できるため、HTMLコンテンツから動的にPDFを生成することから、既存のドキュメントからデータを抽出することに至るまで、様々なタスクにおいて不可欠なツールとなります。 この多用途ライブラリはPDF関連機能を簡素化し、Webアプリケーション、デスクトップソフトウェア、または効率的なPDF処理を必要とするあらゆる.NETプロジェクトに取り組む開発者向けの包括的な機能セットを提供します。

IronPDFのインストール

コード例に進む前に、IronPDFをインストールする必要があります。 この操作は、NuGetパッケージマネージャーコンソールを使用するか、プロジェクトにIronPDFライブラリを追加することで行うことができます。 次の手順は、インストールプロセスを説明しています:

  1. NuGetパッケージマネージャーコンソール:
    :ProductInstall
  1. パッケージマネージャーUI: NuGetパッケージマネージャーUIで「IronPDF」を検索し、最新バージョンをインストールしてください。

    IronPDFをインストールすると、C#アプリケーションでPDFファイル処理にその機能を活用する準備が整います。

5.2. IronPDFでStructとClassを使用する

using IronPdf;
using System;
// Sample class
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
// Sample struct
struct Point
{
    public int X { get; set; }
    public int Y { get; set; }
}
class Program
{
    static void Main()
    {
        // Sample instances of class and struct
        Person person = new Person { Name = "John Doe", Age = 30 };
        Point point = new Point { X = 10, Y = 20 };
        // Create a new PDF document
        var renderer = new ChromePdfRenderer();
        // Add content with information from class and struct
        string content = $@"<!DOCTYPE html>
                            <html>
                            <body>
                                <h1>Information in IronPDF</h1>
                                <p>Name: {person.Name}</p>
                                <p>Age: {person.Age}</p>
                                <p>Point X: {point.X}</p>
                                <p>Point Y: {point.Y}</p>
                            </body>
                            </html>";
        // Render HTML content to PDF
        var pdf = renderer.RenderHtmlAsPdf(content);
        // Save the PDF to a file
        pdf.SaveAs("InformationDocument.pdf");
    }
}
using IronPdf;
using System;
// Sample class
class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}
// Sample struct
struct Point
{
    public int X { get; set; }
    public int Y { get; set; }
}
class Program
{
    static void Main()
    {
        // Sample instances of class and struct
        Person person = new Person { Name = "John Doe", Age = 30 };
        Point point = new Point { X = 10, Y = 20 };
        // Create a new PDF document
        var renderer = new ChromePdfRenderer();
        // Add content with information from class and struct
        string content = $@"<!DOCTYPE html>
                            <html>
                            <body>
                                <h1>Information in IronPDF</h1>
                                <p>Name: {person.Name}</p>
                                <p>Age: {person.Age}</p>
                                <p>Point X: {point.X}</p>
                                <p>Point Y: {point.Y}</p>
                            </body>
                            </html>";
        // Render HTML content to PDF
        var pdf = renderer.RenderHtmlAsPdf(content);
        // Save the PDF to a file
        pdf.SaveAs("InformationDocument.pdf");
    }
}
Imports IronPdf
Imports System
' Sample class
Friend Class Person
	Public Property Name() As String
	Public Property Age() As Integer
End Class
' Sample struct
Friend Structure Point
	Public Property X() As Integer
	Public Property Y() As Integer
End Structure
Friend Class Program
	Shared Sub Main()
		' Sample instances of class and struct
		Dim person As New Person With {
			.Name = "John Doe",
			.Age = 30
		}
		Dim point As New Point With {
			.X = 10,
			.Y = 20
		}
		' Create a new PDF document
		Dim renderer = New ChromePdfRenderer()
		' Add content with information from class and struct
		Dim content As String = $"<!DOCTYPE html>
                            <html>
                            <body>
                                <h1>Information in IronPDF</h1>
                                <p>Name: {person.Name}</p>
                                <p>Age: {person.Age}</p>
                                <p>Point X: {point.X}</p>
                                <p>Point Y: {point.Y}</p>
                            </body>
                            </html>"
		' Render HTML content to PDF
		Dim pdf = renderer.RenderHtmlAsPdf(content)
		' Save the PDF to a file
		pdf.SaveAs("InformationDocument.pdf")
	End Sub
End Class
VB   C#
  • Personは、NameAgeプロパティを持つ人物を表すサンプルクラスです。
  • Point は、2D座標系での点を表すサンプル構造体で、XY のプロパティを持ちます。
  • Person クラスのインスタンスと Point 構造体が作成されます。
  • HTMLコンテンツはPDFドキュメントにレンダリングされ、「InformationDocument.pdf」として保存されます。

出力PDFファイル

C# 構造体 vs クラス(開発者のための仕組み):図3 - 前のコードから出力されたPDFファイル

結論

結論として、C#の構造体とクラスを使用する選択は、アプリケーションの具体的な要件と特性によります。 クラスは、参照型であるため、状態と動作を持つ複雑なエンティティのモデリングに適しており、継承をサポートし、共有インスタンスを容易にします。 一方、値型としての構造体は、値セマンティクスを持つ軽量なデータ構造に最適であり、スタック割り当てや直接アクセスにおける性能上の利点を提供します。

IronPDFは**評価のための無料トライアルライセンスユーザーにとって、IronPDFの機能と特徴を知る良い機会です。 IronPDFの詳細については、以下をご覧ください。包括的なIronPDFドキュメントまた、IronPDFを使ってPDFファイルを作成するための詳しいチュートリアルはIronPDF PDF生成チュートリアル.

< 以前
C#で配列を初期化する方法(開発者向け)
次へ >
NPlot C#(開発者向けの使用方法)