푸터 콘텐츠로 바로가기
.NET 도움말

C# Record Vs Class (How It Works For Developers)

In the world of C#, two primary structures are utilized to model and encapsulate data: classes and records. Both serve as reference types but differ significantly in their intended use, behavior, and how they handle equality. This guide will dissect these differences, providing clear examples and practical uses to aid developers in choosing the right structure for their needs. We'll also learn about the IronPDF library.

Classes in C#: The Basics

Classes have been a cornerstone of object-oriented programming in C#, designed to encapsulate data and behavior. They are reference types, meaning two class instances with the same values are considered two separate objects. This distinction is crucial when comparing two class instances; the default comparison is reference-based, not value-based.

public class Person
{
    public int Id { get; set; }
    public string FullName { get; set; }
}
public class Person
{
    public int Id { get; set; }
    public string FullName { get; set; }
}
$vbLabelText   $csharpLabel

In the example above, Person is a class with Id and FullName properties. Even if two Person instances have identical Id and FullName values, they are not considered equal by default because they are two different references in memory.

Records in C#: Immutable Data Structures

Introduced in C#, the record type is a newer addition aimed at simplifying the creation of immutable data structures, providing a robust alternative to traditional class structures. Unlike classes, records offer value-based equality semantics, making them ideal for data transfer objects or small data structures with little or no behavior.

public record Person(int Id, string FullName);
public record Person(int Id, string FullName);
$vbLabelText   $csharpLabel

In the above example, the record definition is more succinct, reducing boilerplate code. Records automatically support nondestructive mutation and value-based comparison. Two record instances with the same values are considered equal, aligning with value semantics.

Practical Uses: When to Use Record vs. Class

Choosing between a class and a record, or other data structures in C#, depends on the complexity of the data you're modeling and the behaviors required by your application. Classes are specifically designed for complex data structures, accommodating behaviors (methods) and allowing for mutable instances as required. Records, on the other hand, are perfect examples of a simple data structure, designed with immutable characteristics and value-based equality, ideal for data that remains constant after creation.

Classes are ideal when your data structure requires encapsulating data and behaviors or when you need to manipulate the data after its creation. This flexibility makes classes a go-to for most traditional object-oriented programming scenarios and when creating complex data structures.

Records shine in scenarios where data immutability is crucial or when you're dealing with simple data structures that primarily serve as data containers. Their built-in value-based equality and concise syntax make them excellent for data transfer objects or value objects.

Value Types and Reference Types

Understanding the difference between value type and reference type in C# is vital. Classes are reference types, meaning variables hold a reference to the actual data in memory. This characteristic leads to the default reference-based equality comparison.

Records, while also reference types, emulate value semantics through their built-in value-based equality, making them behave somewhat like value types in comparisons.

Code Examples: Implementing Classes and Records

Let's implement a class and a record to highlight the differences in syntax and behavior.

Class Implementation:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }

    public Product(int id, string name)
    {
        Id = id;
        Name = name;
    }
}
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }

    public Product(int id, string name)
    {
        Id = id;
        Name = name;
    }
}
$vbLabelText   $csharpLabel

Record Implementation:

public record Product(int Id, string Name);
public record Product(int Id, string Name);
$vbLabelText   $csharpLabel

Notice the brevity and simplicity of the record implementation. The record automatically generates the constructor, properties, and methods for value-based equality.

Understanding Equality: Reference vs. Value

The core difference between class and record types in C# indeed lies in how they handle equality:

  1. Classes use reference equality by default, meaning two instances are equal if they point to the same memory location.

  2. Records use value equality by default, considering two instances equal if their properties have the same values.

Reference Equality Example (Class)

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

var classInstance1 = new Person { Id = 1, Name = "Iron Software" };
var classInstance2 = new Person { Id = 1, Name = "Iron Software" };
Console.WriteLine(classInstance1 == classInstance2); // Outputs: False
public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

var classInstance1 = new Person { Id = 1, Name = "Iron Software" };
var classInstance2 = new Person { Id = 1, Name = "Iron Software" };
Console.WriteLine(classInstance1 == classInstance2); // Outputs: False
$vbLabelText   $csharpLabel

Two instances of a class with the same property values are not considered equal because they are different objects in memory.

Value Equality Example

public record Person(int Id, string Name);

var recordInstance1 = new Person(1, "Iron Software");
var recordInstance2 = new Person(1, "Iron Software");
Console.WriteLine(recordInstance1 == recordInstance2); // Outputs: True
public record Person(int Id, string Name);

var recordInstance1 = new Person(1, "Iron Software");
var recordInstance2 = new Person(1, "Iron Software");
Console.WriteLine(recordInstance1 == recordInstance2); // Outputs: True
$vbLabelText   $csharpLabel

Two instances of a record with the same property values are considered equal by default.

Advanced Features: Records

Records come with several advanced features that cater to the need for immutable data structures and value-based equality. The with expression allows for creating a new record instance by copying an existing record but with some properties modified, demonstrating nondestructive mutation.

Nondestructive Mutation with Records:

var originalRecord = new Person(1, "Doe");
var modifiedRecord = originalRecord with { Name = "Iron Developer" };
var originalRecord = new Person(1, "Doe");
var modifiedRecord = originalRecord with { Name = "Iron Developer" };
$vbLabelText   $csharpLabel

This feature is handy when working with immutable data structures, as it provides a way to "modify" an instance without altering the original data.

Introduction of IronPDF Library

IronPDF webpage

IronPDF is a PDF library for .NET developers, offering a comprehensive solution for creating, editing, and managing PDF documents directly within .NET applications. It simplifies the PDF generation process by allowing developers to convert HTML into PDFs, CSS, JavaScript, and images into PDFs. IronPDF supports a variety of .NET frameworks and project types, including web, desktop, and console applications, across multiple operating systems such as Windows, Linux, and macOS.

Beyond PDF creation, IronPDF provides capabilities for editing PDFs, setting properties and security, working with PDF forms, and extracting content. It's designed to meet the needs of developers looking for a reliable tool to integrate PDF functionality into their .NET projects.

Code Example

Creating a PDF in C# using IronPDF can be achieved with both classes and records. Below are examples of both approaches to generate a simple PDF document. The primary difference between classes and records in C# lies in their intended use: classes are mutable by default and designed for traditional object-oriented programming, while records are immutable and designed for value-based programming, making them ideal for data modeling.

Using a Class

In this example, we'll define a PdfGenerator class that contains a method to create a PDF from a given HTML string.

using IronPdf;
using System;

public class PdfGenerator
{
    public string HtmlContent { get; set; }

    public PdfGenerator(string htmlContent)
    {
        HtmlContent = htmlContent;
    }

    public void GeneratePdf(string filePath)
    {
        var renderer = new ChromePdfRenderer();
        var pdfDocument = renderer.RenderHtmlAsPdf(HtmlContent);
        pdfDocument.SaveAs(filePath);
    }
}

class Program
{
    public static void Main(string[] args)
    {
        License.LicenseKey = "License-Key"; // Set your license key here

        var generator = new PdfGenerator("<h1>Hello, World from Class!</h1>");
        generator.GeneratePdf("ClassExample.pdf");
    }
}
using IronPdf;
using System;

public class PdfGenerator
{
    public string HtmlContent { get; set; }

    public PdfGenerator(string htmlContent)
    {
        HtmlContent = htmlContent;
    }

    public void GeneratePdf(string filePath)
    {
        var renderer = new ChromePdfRenderer();
        var pdfDocument = renderer.RenderHtmlAsPdf(HtmlContent);
        pdfDocument.SaveAs(filePath);
    }
}

class Program
{
    public static void Main(string[] args)
    {
        License.LicenseKey = "License-Key"; // Set your license key here

        var generator = new PdfGenerator("<h1>Hello, World from Class!</h1>");
        generator.GeneratePdf("ClassExample.pdf");
    }
}
$vbLabelText   $csharpLabel

Output:

Outputted PDF from the class example

Using a Record

In contrast, a record in C# is immutable after initialization. Here's how you could achieve a similar outcome with a record, utilizing with expressions for modifications, which essentially return a new instance of the record with the desired changes.

using IronPdf;
using System;

public record PdfGeneratorRecord(string HtmlContent)
{
    public void GeneratePdf(string filePath)
    {
        var renderer = new ChromePdfRenderer();
        var pdfDocument = renderer.RenderHtmlAsPdf(this.HtmlContent);
        pdfDocument.SaveAs(filePath);
    }
}

class Program
{
    public static void Main(string[] args)
    {
        License.LicenseKey = "License-Key"; // Set your license key here

        var recordGenerator = new PdfGeneratorRecord("<h1>Hello, World from Record!</h1>");
        recordGenerator.GeneratePdf("RecordExample.pdf");
    }
}
using IronPdf;
using System;

public record PdfGeneratorRecord(string HtmlContent)
{
    public void GeneratePdf(string filePath)
    {
        var renderer = new ChromePdfRenderer();
        var pdfDocument = renderer.RenderHtmlAsPdf(this.HtmlContent);
        pdfDocument.SaveAs(filePath);
    }
}

class Program
{
    public static void Main(string[] args)
    {
        License.LicenseKey = "License-Key"; // Set your license key here

        var recordGenerator = new PdfGeneratorRecord("<h1>Hello, World from Record!</h1>");
        recordGenerator.GeneratePdf("RecordExample.pdf");
    }
}
$vbLabelText   $csharpLabel

Output:

Outputted PDF from the record example

These examples illustrate how to generate a PDF file using IronPDF with both a class and a record in C#. The choice between using a class or a record depends on your specific needs: if you need objects that are going to be modified after creation, a class might be more appropriate. If you're dealing with data that shouldn't change once it's been created, or you appreciate the syntactical simplicity and safety of immutability, a record could be the better choice.

Conclusion

IronPDF licensing page

In conclusion, classes offer traditional object-oriented features with mutable state and reference-based equality, while records provide a modern approach to defining immutable data structures with value-based equality.

The choice between using a class or a record should be guided by the specific requirements of your application, considering factors like the need for immutability, the complexity of the data structure, and the preferred method of equality comparison. Discover IronPDF's Free Trial for those looking to integrate PDF functionality into their .NET applications, with licenses starting from $799.

자주 묻는 질문

C# 클래스와 레코드의 주요 차이점은 무엇인가요?

C# 클래스와 레코드는 모두 데이터를 모델링하고 캡슐화하는 데 사용되는 참조 유형이지만 동등성과 불변성을 처리하는 방식이 다릅니다. 클래스는 참조 동등성을 사용하므로 두 인스턴스가 동일한 메모리 위치를 가리키면 동일한 것으로 간주됩니다. 반면에 레코드는 값 동일성을 사용하여 두 인스턴스의 속성이 동일한 값을 가지면 동일한 것으로 간주하며 기본적으로 변경 불가능하도록 설계되어 있습니다.

C#에서 클래스를 사용할지 레코드를 사용할지 어떻게 결정하나요?

C#에서 클래스를 사용할지 레코드를 사용할지는 특정 요구 사항에 따라 달라집니다. 변경 가능한 인스턴스가 필요하거나 객체 지향 프로그래밍의 일반적인 데이터 및 동작을 캡슐화하려는 경우 클래스를 사용하세요. 구조가 단순하고 변경 불가능하며 데이터 전송 개체와 같이 값 기반 동일성이 필요한 경우에는 레코드를 선택하세요.

IronPDF 라이브러리는 .NET에서 PDF 생성을 어떻게 지원하나요?

IronPDF는 PDF 문서의 생성, 편집 및 관리를 간소화하는 강력한 .NET용 PDF 라이브러리입니다. 개발자가 HTML, CSS, JavaScript, 이미지를 PDF로 변환할 수 있으며 다양한 .NET 프레임워크와 운영 체제를 지원하므로 .NET 개발자에게 필수적인 도구입니다.

PDF 생성 프로젝트에서 C# 클래스와 레코드를 모두 사용할 수 있나요?

예, C# 클래스와 레코드 모두 PDF 생성 프로젝트에 사용할 수 있습니다. 선택은 로직에 변경 가능한 데이터 구조가 필요한지 또는 변경 불가능한 데이터 구조가 필요한지에 따라 달라집니다. 예를 들어, IronPDF는 두 가지 구조 모두에서 원활하게 작동하여 PDF를 생성하고 조작할 수 있습니다.

C# 레코드에서 불변성은 어떤 역할을 하나요?

불변성은 C# 레코드의 핵심 기능입니다. 일단 생성된 레코드의 속성은 변경할 수 없으며, 이는 값 기반 동등성 의미론에 부합합니다. 이러한 설계 덕분에 레코드는 데이터 전송 개체와 같이 데이터 일관성과 무결성이 중요한 시나리오에 이상적입니다.

IronPDF는 .NET 애플리케이션의 PDF 기능을 어떻게 향상시키나요?

IronPDF는 HTML을 PDF로 변환, PDF 편집, 문서 보안 관리와 같은 기능을 제공하여 .NET 애플리케이션의 PDF 기능을 향상시킵니다. 양식 작업, 콘텐츠 추출, 다양한 .NET 환경 간의 원활한 통합을 지원하여 PDF 문서 처리를 간소화합니다.

C# 레코드 문맥에서 'with' 표현은 무엇인가요?

C# 레코드에서 'with' 표현식은 비파괴적 변이에 사용됩니다. 이를 통해 개발자는 기존 레코드를 복사하되 일부 속성을 수정하여 새 레코드 인스턴스를 생성할 수 있으며, 원본 데이터는 변경되지 않도록 보장합니다.

레코드가 데이터 전송 개체에 적합한 것으로 간주되는 이유는 무엇인가요?

레코드는 값 기반의 동일성을 가진 불변 구조를 정의하기 위한 간결한 구문을 제공하기 때문에 데이터 전송 개체에 적합한 것으로 간주됩니다. 이렇게 하면 데이터 무결성이 유지되고 동일한 값을 가진 인스턴스가 동일한 것으로 취급되며, 이는 데이터 전송 시나리오에서 종종 요구되는 사항입니다.

커티스 차우
기술 문서 작성자

커티스 차우는 칼턴 대학교에서 컴퓨터 과학 학사 학위를 취득했으며, Node.js, TypeScript, JavaScript, React를 전문으로 하는 프론트엔드 개발자입니다. 직관적이고 미적으로 뛰어난 사용자 인터페이스를 만드는 데 열정을 가진 그는 최신 프레임워크를 활용하고, 잘 구성되고 시각적으로 매력적인 매뉴얼을 제작하는 것을 즐깁니다.

커티스는 개발 분야 외에도 사물 인터넷(IoT)에 깊은 관심을 가지고 있으며, 하드웨어와 소프트웨어를 통합하는 혁신적인 방법을 연구합니다. 여가 시간에는 게임을 즐기거나 디스코드 봇을 만들면서 기술에 대한 애정과 창의성을 결합합니다.