Przejdź do treści stopki
POMOC .NET

C# Record a Class (jak to działa dla programistów)

W świecie języka C# do modelowania i enkapsulacji danych wykorzystywane są dwie podstawowe struktury: klasy i rekordy. Oba służą jako typy referencyjne, ale znacznie różnią się pod względem przeznaczenia, zachowania i sposobu traktowania równości. W niniejszym przewodniku przeanalizujemy te różnice, podając jasne przykłady i praktyczne zastosowania, aby pomóc programistom w wyborze struktury odpowiedniej do ich potrzeb. Poznamy również bibliotekę IronPDF.

Klasy w języku C#: podstawy

Klasy są podstawą programowania obiektowego w języku C# i zostały zaprojektowane w celu hermetyzacji danych i zachowań. Są to typy referencyjne, co oznacza, że dwie instancje klasy o tych samych wartościach są traktowane jako dwa odrębne obiekty. To rozróżnienie ma kluczowe znaczenie przy porównywaniu dwóch instancji klasy; Domyślne porównanie opiera się na odniesieniach, a nie na wartościach.

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; }
}
Public Class Person
	Public Property Id() As Integer
	Public Property FullName() As String
End Class
$vbLabelText   $csharpLabel

W powyższym przykładzie Person jest klasą posiadającą właściwości Id i FullName. Nawet jeśli dwie instancje klasy Person mają identyczne wartości Id i FullName, domyślnie nie są one traktowane jako równe, ponieważ są to dwa różne odwołania w pamięci.

Rekordy w C#: Niezmienne struktury danych

Wprowadzony w języku C# typ record jest nowym dodatkiem mającym na celu uproszczenie tworzenia niezmiennych struktur danych, stanowiącym solidną alternatywę dla tradycyjnych struktur klas. W przeciwieństwie do klas, rekordy oferują semantykę równości opartą na wartościach, co czyni je idealnymi dla obiektów transferu danych lub małych struktur danych o niewielkim lub zerowym zachowaniu.

public record Person(int Id, string FullName);
public record Person(int Id, string FullName);
'INSTANT VB TODO TASK: C# 'records' are not converted by Instant VB:
'public record Person(int Id, string FullName)
$vbLabelText   $csharpLabel

W powyższym przykładzie definicja rekordu jest bardziej zwięzła, co ogranicza ilość kodu szablonowego. Rekordy automatycznie obsługują mutacje nieniszczące i porównania oparte na wartościach. Dwie instancje rekordów o tych samych wartościach są uznawane za równe, zgodnie z semantyką wartości.

Zastosowania praktyczne: kiedy używać Record, a kiedy Class

Wybór między klasą a rekordem lub innymi strukturami danych w języku C# zależy od złożoności modelowanych danych oraz zachowań wymaganych przez aplikację. Klasy są specjalnie zaprojektowane pod kątem złożonych struktur danych, uwzględniając zachowania (metody) i umożliwiając tworzenie instancji zmiennych w razie potrzeby. Z drugiej strony rekordy są doskonałym przykładem prostej struktury danych, zaprojektowanej z niezmiennymi cechami i równością opartą na wartościach, idealnej dla danych, które pozostają niezmienne po utworzeniu.

Klasy są idealnym rozwiązaniem, gdy struktura danych wymaga hermetyzacji danych i zachowań lub gdy konieczne jest manipulowanie danymi po ich utworzeniu. Ta elastyczność sprawia, że klasy są najczęściej wybieranym rozwiązaniem w większości tradycyjnych scenariuszy programowania obiektowego oraz podczas tworzenia złożonych struktur danych.

Rekordy sprawdzają się w sytuacjach, w których niezmienność danych ma kluczowe znaczenie lub gdy mamy do czynienia z prostymi strukturami danych, które służą przede wszystkim jako kontenery danych. Wbudowana równość oparta na wartościach oraz zwięzła składnia sprawiają, że doskonale nadają się one do obiektów transferu danych lub obiektów wartości.

Typy wartości i typy referencyjne

Zrozumienie różnicy między typem wartości a typem referencyjnym w języku C# ma kluczowe znaczenie. Klasy są typami referencyjnymi, co oznacza, że zmienne przechowują odwołanie do rzeczywistych danych w pamięci. Ta cecha prowadzi do domyślnego porównania równości opartego na odniesieniach.

Rekordy, choć są typami referencyjnymi, emulują semantykę wartości poprzez wbudowaną równość opartą na wartościach, co sprawia, że w porównaniach zachowują się nieco jak typy wartościowe.

Przykłady kodu: Implementacja klas i rekordów

Zaimplementujmy klasę i rekord, aby podkreślić różnice w składni i zachowaniu.

Implementacja klasy:

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;
    }
}
Public Class Product
	Public Property Id() As Integer
	Public Property Name() As String

	Public Sub New(ByVal id As Integer, ByVal name As String)
		Me.Id = id
		Me.Name = name
	End Sub
End Class
$vbLabelText   $csharpLabel

Wdrożenie Record:

public record Product(int Id, string Name);
public record Product(int Id, string Name);
'INSTANT VB TODO TASK: C# 'records' are not converted by Instant VB:
'public record Product(int Id, string Name)
$vbLabelText   $csharpLabel

Zwróć uwagę na zwięzłość i prostotę implementacji rekordu. Rekord automatycznie generuje konstruktor, właściwości i metody dla równości opartej na wartościach.

Zrozumienie równości: referencja a wartość

Podstawowa różnica między typami klas i rekordów w języku C# polega rzeczywiście na sposobie traktowania równości:

  1. Klasy domyślnie stosują równość referencyjną, co oznacza, że dwie instancje są równe, jeśli wskazują na tę samą lokalizację w pamięci.

  2. Rekordy domyślnie stosują równość wartości, uznając dwie instancje za równe, jeśli ich właściwości mają te same wartości.

Przykład równości referencyjnej (klasa)

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
Public Class Person
	Public Property Id() As Integer
	Public Property Name() As String
End Class

Private classInstance1 = New Person With {
	.Id = 1,
	.Name = "Iron Software"
}
Private classInstance2 = New Person With {
	.Id = 1,
	.Name = "Iron Software"
}
Console.WriteLine(classInstance1 = classInstance2) ' Outputs: False
$vbLabelText   $csharpLabel

Dwa egzemplarze klasy o tych samych wartościach właściwości nie są uważane za równe, ponieważ są to różne obiekty w pamięci.

Przykład równości wartości

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
'INSTANT VB TODO TASK: C# 'records' are not converted by Instant VB:
'public record Person(int Id, string Name)

Private recordInstance1 = New Person(1, "Iron Software")
Private recordInstance2 = New Person(1, "Iron Software")
Console.WriteLine(recordInstance1 = recordInstance2) ' Outputs: True
$vbLabelText   $csharpLabel

Dwa egzemplarze rekordu o tych samych wartościach właściwości są domyślnie traktowane jako równe.

Funkcje zaawansowane: Rekordy

Rekordy posiadają kilka zaawansowanych funkcji, które zaspokajają potrzebę niezmiennych struktur danych i równości opartej na wartościach. Wyrażenie with pozwala na utworzenie nowej instancji rekordu poprzez skopiowanie istniejącego rekordu, ale z pewnymi zmodyfikowanymi właściwościami, co stanowi przykład mutacji nieniszczącej.

Mutacja nieniszcząca z wykorzystaniem rekordów:

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" };
Dim originalRecord = New Person(1, "Doe")
'INSTANT VB TODO TASK: C# 'with expressions' are not converted by Instant VB:
'var modifiedRecord = originalRecord with { Name = "Iron Developer" }
$vbLabelText   $csharpLabel

Ta funkcja jest przydatna podczas pracy z niezmiennymi strukturami danych, ponieważ umożliwia "modyfikację" instancji bez zmiany oryginalnych danych.

Wprowadzenie do biblioteki IronPDF

Strona internetowa IronPDF

IronPDF for .NET to biblioteka PDF dla programistów .NET, oferująca kompleksowe rozwiązanie do tworzenia, edycji i zarządzania dokumentami PDF bezpośrednio w aplikacjach .NET. Upraszcza proces generowania plików PDF, umożliwiając programistom konwersję HTML na PDF, a także CSS, JavaScript i obrazów na PDF. IronPDF obsługuje różne frameworki .NET i typy projektów, w tym aplikacje internetowe, desktopowe i konsolowe, na wielu systemach operacyjnych, takich jak Windows, Linux i macOS.

Oprócz tworzenia plików PDF, IronPDF oferuje funkcje edycji plików PDF, ustawiania właściwości i zabezpieczeń, pracy z formularzami PDF oraz wyodrębniania treści. Został zaprojektowany z myślą o programistach poszukujących niezawodnego narzędzia do integracji funkcji PDF z ich projektami .NET.

Przykład kodu

Tworzenie pliku PDF w języku C# przy użyciu IronPDF można osiągnąć zarówno za pomocą klas, jak i rekordów. Poniżej znajdują się przykłady obu podejść do generowania prostego dokumentu PDF. Główna różnica między klasami a rekordami w języku C# polega na ich przeznaczeniu: klasy są domyślnie zmienne i zaprojektowane z myślą o tradycyjnym programowaniu obiektowym, podczas gdy rekordy są niezmienne i zaprojektowane z myślą o programowaniu opartym na wartościach, co czyni je idealnymi do modelowania danych.

Korzystanie z klasy

W tym przykładzie zdefiniujemy klasę PdfGenerator, która zawiera metodę do tworzenia pliku PDF na podstawie podanego ciągu znaków HTML.

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");
    }
}
Imports IronPdf
Imports System

Public Class PdfGenerator
	Public Property HtmlContent() As String

	Public Sub New(ByVal htmlContent As String)
		Me.HtmlContent = htmlContent
	End Sub

	Public Sub GeneratePdf(ByVal filePath As String)
		Dim renderer = New ChromePdfRenderer()
		Dim pdfDocument = renderer.RenderHtmlAsPdf(HtmlContent)
		pdfDocument.SaveAs(filePath)
	End Sub
End Class

Friend Class Program
	Public Shared Sub Main(ByVal args() As String)
		License.LicenseKey = "License-Key" ' Set your license key here

		Dim generator = New PdfGenerator("<h1>Hello, World from Class!</h1>")
		generator.GeneratePdf("ClassExample.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

Wynik:

Wygenerowany plik PDF z przykładu z zajęć

Korzystanie z rekordu

Natomiast rekord w języku C# jest niezmienny po inicjalizacji. Oto jak można osiągnąć podobny rezultat w przypadku rekordu, wykorzystując wyrażenia with do modyfikacji, które zasadniczo zwracają nową instancję rekordu z pożądanymi zmianami.

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");
    }
}
Imports IronPdf
Imports System

'INSTANT VB TODO TASK: C# 'records' are not converted by Instant VB:
'public record PdfGeneratorRecord(string HtmlContent)
'{
'	public void GeneratePdf(string filePath)
'	{
'		var renderer = New ChromePdfRenderer();
'		var pdfDocument = renderer.RenderHtmlAsPdf(Me.HtmlContent);
'		pdfDocument.SaveAs(filePath);
'	}
'}

Friend Class Program
	Public Shared Sub Main(ByVal args() As String)
		License.LicenseKey = "License-Key" ' Set your license key here

		Dim recordGenerator = New PdfGeneratorRecord("<h1>Hello, World from Record!</h1>")
		recordGenerator.GeneratePdf("RecordExample.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

Wynik:

Wygenerowany plik PDF na podstawie przykładowego zapisu

Poniższe przykłady ilustrują, jak wygenerować plik PDF przy użyciu IronPDF, korzystając zarówno z klasy, jak i rekordu w języku C#. Wybór między użyciem klasy a rekordu zależy od konkretnych potrzeb: jeśli potrzebujesz obiektów, które będą modyfikowane po utworzeniu, klasa może być bardziej odpowiednia. Jeśli masz do czynienia z danymi, które nie powinny ulegać zmianom po utworzeniu, lub cenisz sobie prostotę składniową i bezpieczeństwo niezmienności, lepszym wyborem może być rekord.

Wnioski

Strona licencyjna IronPDF

Podsumowując, klasy oferują tradycyjne funkcje obiektowe ze stanem zmiennym i równością opartą na referencjach, podczas gdy rekordy zapewniają nowoczesne podejście do definiowania niezmiennych struktur danych z równością opartą na wartościach.

Wybór między użyciem klasy a rekordu powinien być podyktowany konkretnymi wymaganiami aplikacji, z uwzględnieniem takich czynników, jak potrzeba niezmienności, złożoność struktury danych oraz preferowana metoda porównywania równości. Odkryj bezpłatną wersję próbną IronPDF dla tych, którzy chcą zintegrować funkcjonalność PDF ze swoimi aplikacjami .NET, z licencjami zaczynającymi się od $799.

Często Zadawane Pytania

Jakie są główne różnice między klasami a rekordami w C#?

Klasy i rekordy w C# są typami referencyjnymi używanymi do modelowania i enkapsulacji danych, ale różnią się sposobem obsługi równości i niemutowalności. Klasy używają równości referencyjnej, co oznacza, że dwie instancje są uznawane za równe, jeśli wskazują na tę samą lokalizację pamięci. Z kolei rekordy używają równości wartościowej, uznając dwie instancje za równe, jeśli ich właściwości mają takie same wartości i są projektowane jako niemutowalne domyślnie.

Jak mogę zdecydować, czy użyć klasy, czy rekordu w C#?

Wybór między klasą a rekordem w C# zależy od Twoich konkretnych wymagań. Użyj klasy, jeśli potrzebujesz mutowalnych instancji lub chcesz enkapsulować dane i zachowania typowe dla programowania obiektowego. Wybierz rekord, jeśli struktura jest prosta, niemutowalna i wymagasz równości opartej na wartościach, na przykład w obiektach transferu danych.

Jak biblioteka IronPDF wspiera generowanie PDF w .NET?

IronPDF to solidna biblioteka PDF dla .NET, która upraszcza tworzenie, edycję i zarządzanie dokumentami PDF. Pozwala programistom konwertować HTML, CSS, JavaScript i obrazy do PDF, wspierając różne frameworki i systemy operacyjne .NET, co czyni ją niezbędnym narzędziem dla programistów .NET.

Czy w projektach związanych z generowaniem plików PDF mogę używać zarówno klas C#, jak i rekordów?

Tak, zarówno klasy C#, jak i rekordy mogą być wykorzystywane w projektach generowania plików PDF. Wybór zależy od tego, czy do realizacji logiki potrzebne są struktury danych zmienne, czy niezmienne. Na przykład IronPDF może płynnie współpracować z obiema strukturami w celu generowania i manipulowania plikami PDF.

Jaką rolę odgrywa niezmienność w rekordach C#?

Niezmienność jest podstawową cechą rekordów w języku C#. Po utworzeniu właściwości rekordu nie można zmienić, co jest zgodne z semantyką równości opartą na wartościach. Taka konstrukcja sprawia, że rekordy idealnie nadają się do scenariuszy, w których spójność i integralność danych mają kluczowe znaczenie, takich jak obiekty transferu danych.

W jaki sposób IronPDF rozszerza funkcjonalność plików PDF w aplikacjach .NET?

IronPDF rozszerza funkcjonalność plików PDF w aplikacjach .NET, oferując takie funkcje, jak konwersja HTML do PDF, edycja plików PDF oraz zarządzanie zabezpieczeniami dokumentów. Obsługuje pracę z formularzami, wyodrębnianie treści oraz płynną integrację w różnych środowiskach .NET, usprawniając w ten sposób przetwarzanie dokumentów PDF.

Czym jest wyrażenie „with” w kontekście rekordów w języku C#?

Wyrażenie „with” w rekordach C# służy do mutacji nieniszczącej. Pozwala programistom na utworzenie nowej instancji rekordu poprzez skopiowanie istniejącej, ale z pewnymi zmodyfikowanymi właściwościami, zapewniając, że oryginalne dane pozostają niezmienione.

Dlaczego rekordy są uważane za odpowiednie obiekty do przesyłania danych?

Rekordy są uważane za odpowiednie obiekty do transferu danych, ponieważ zapewniają zwięzłą składnię do definiowania niezmiennych struktur z równością opartą na wartościach. Zapewnia to zachowanie integralności danych oraz traktowanie instancji o identycznych wartościach jako równych, co jest często pożądane w scenariuszach transferu danych.

Jacob Mellor, Dyrektor Technologiczny @ Team Iron
Dyrektor ds. technologii

Jacob Mellor jest Chief Technology Officer w Iron Software i wizjonerskim inżynierem, pionierem technologii C# PDF. Jako pierwotny deweloper głównej bazy kodowej Iron Software, kształtuje architekturę produktów firmy od jej początku, przekształcając ją wspólnie z CEO Cameron Rimington w firmę liczą...

Czytaj więcej

Zespol wsparcia Iron

Jestesmy online 24 godziny, 5 dni w tygodniu.
Czat
Email
Zadzwon do mnie