Przejdź do treści stopki
POMOC .NET

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

Operator "nameof", wprowadzony w C# 6.0, jest konstrukcją kompilacyjną zaprojektowaną w celu rozwiązania problemu odwoływania się do elementów programu po ich nazwach oraz cichych błędów w czasie wykonywania. Jego głównym celem jest wyeliminowanie konieczności stosowania sztywno zakodowanych ciągów znaków, oferując podejście łatwiejsze w utrzymaniu i odporne na błędy. W tym artykule omówimy operator nameof w języku C#, a także przedstawimy bibliotekę IronPDF dostępną w NuGet, służącą do programowego generowania dokumentów PDF.

Podstawowa składnia operatora "nameof"

Podstawowa składnia operatora "nameof" jest prosta. Przyjmuje element jako argument i zwraca jego nazwę jako ciąg znaków. Rozważmy następujący przykład:

static void Main()
{
    // Declare a string variable
    string myVariable = nameof(myVariable);
    Console.WriteLine(myVariable); // Output: "myVariable"
}
static void Main()
{
    // Declare a string variable
    string myVariable = nameof(myVariable);
    Console.WriteLine(myVariable); // Output: "myVariable"
}
Shared Sub Main()
	' Declare a string variable
	Dim myVariable As String = NameOf(myVariable)
	Console.WriteLine(myVariable) ' Output: "myVariable"
End Sub
$vbLabelText   $csharpLabel

W tym przypadku "nameof(myVariable)" zwraca ciąg znaków "myVariable". Operator ten można zastosować do różnych elementów kodu, w tym zmiennych, typów, elementów składowych i innych.

Zalety operatora "nameof"

Łatwość utrzymania kodu

Jedną z wyróżniających się zalet operatora "nameof" jest jego pozytywny wpływ na łatwość utrzymania kodu. Zamiast na stałe zakodować nazwy jako ciągi znaków, programiści mogą użyć 'nameof', co gwarantuje, że odniesienia zostaną automatycznie zaktualizowane w przypadku zmiany nazw.

static void Main()
{
    // Without using nameof
    Logger.Log("Error: The variable 'myVariable' is null.");
    // Using nameof for improved maintainability
    Logger.Log($"Error: The variable '{nameof(myVariable)}' is null.");
}
static void Main()
{
    // Without using nameof
    Logger.Log("Error: The variable 'myVariable' is null.");
    // Using nameof for improved maintainability
    Logger.Log($"Error: The variable '{nameof(myVariable)}' is null.");
}
Shared Sub Main()
	' Without using nameof
	Logger.Log("Error: The variable 'myVariable' is null.")
	' Using nameof for improved maintainability
	Logger.Log($"Error: The variable '{NameOf(myVariable)}' is null.")
End Sub
$vbLabelText   $csharpLabel

Bezpieczeństwo w czasie kompilacji

'nameof' zwiększa bezpieczeństwo w czasie kompilacji, eliminując ryzyko literówek lub niespójności w nazwach. Wszelkie błędy ortograficzne lub modyfikacje nazwy zmiennej powodują błąd kompilacji, co zmniejsza ryzyko wystąpienia problemów podczas działania programu.

static void Main()
{
    // Compile-time error if 'myVariable' is misspelled
    string myVariable;
    string variableName = nameof(myVariable);

    Console.WriteLine(variableName);
}
static void Main()
{
    // Compile-time error if 'myVariable' is misspelled
    string myVariable;
    string variableName = nameof(myVariable);

    Console.WriteLine(variableName);
}
Shared Sub Main()
	' Compile-time error if 'myVariable' is misspelled
	Dim myVariable As String
	Dim variableName As String = NameOf(myVariable)

	Console.WriteLine(variableName)
End Sub
$vbLabelText   $csharpLabel

Obsługa refaktoryzacji

Operator "nameof" płynnie integruje się z narzędziami do refaktoryzacji, zapewniając bezproblemową obsługę podczas zmiany nazw zmiennych, typów lub elementów składowych. Wszystkie odniesienia typu "nameof" są aktualizowane automatycznie.

static void Main()
{
    // Before renaming local variable 'myVariable' to 'newVariable'
    string myVariableNameChange = nameof(myVariableNameChange);
    // After renaming local variable 'myVariable' to 'newVariable'
    string newVariableNameChange = nameof(newVariableNameChange);

    Console.WriteLine(newVariableNameChange);
}
static void Main()
{
    // Before renaming local variable 'myVariable' to 'newVariable'
    string myVariableNameChange = nameof(myVariableNameChange);
    // After renaming local variable 'myVariable' to 'newVariable'
    string newVariableNameChange = nameof(newVariableNameChange);

    Console.WriteLine(newVariableNameChange);
}
Shared Sub Main()
	' Before renaming local variable 'myVariable' to 'newVariable'
	Dim myVariableNameChange As String = NameOf(myVariableNameChange)
	' After renaming local variable 'myVariable' to 'newVariable'
	Dim newVariableNameChange As String = NameOf(newVariableNameChange)

	Console.WriteLine(newVariableNameChange)
End Sub
$vbLabelText   $csharpLabel

Ulepszone debugowanie

Podczas debugowania 'nameof' sprawia, że kod jest bardziej czytelny i zawiera więcej informacji. Komunikaty logowania, komunikaty o wyjątkach i inne dane wyjściowe debugowania stają się zwięzłe i adekwatne do kontekstu.

static void Main()
{
    // Without using nameof
    // throw new ArgumentNullException("myVariable", "The variable cannot be null."); 
    // Using nameof for improved debugging 
    throw new ArgumentNullException(nameof(myVariable), "The variable cannot be null.");
}
static void Main()
{
    // Without using nameof
    // throw new ArgumentNullException("myVariable", "The variable cannot be null."); 
    // Using nameof for improved debugging 
    throw new ArgumentNullException(nameof(myVariable), "The variable cannot be null.");
}
Shared Sub Main()
	' Without using nameof
	' throw new ArgumentNullException("myVariable", "The variable cannot be null."); 
	' Using nameof for improved debugging 
	Throw New ArgumentNullException(NameOf(myVariable), "The variable cannot be null.")
End Sub
$vbLabelText   $csharpLabel

W tym przypadku throw new ArgumentNullException zgłasza wyjątek, jeśli zmienna nie została zadeklarowana.

Praktyczne zastosowania operatora "nameof"

Refleksja

Podczas pracy z refleksją operator "nameof" ułatwia uzyskiwanie nazw typów, właściwości lub metod bez użycia sztywno zakodowanych ciągów znaków.

Type type = typeof(MyClass);
string typeName = nameof(MyClass);
Type type = typeof(MyClass);
string typeName = nameof(MyClass);
Dim type As Type = GetType([MyClass])
Dim typeName As String = NameOf([MyClass])
$vbLabelText   $csharpLabel

Przykładowa klasa MyClass może być łańcuchem zakodowanym na stałe, ale możemy użyć refleksji, aby uzyskać nazwę klasy dynamicznie. Zmienna type zawiera nazwę klasy, a następnie słowo kluczowe nameof służy do uzyskania nazwy instancji klasy. To nie są te same nazwy.

Rejestrowanie i obsługa wyjątków

'nameof' okazuje się nieoceniony w instrukcjach logowania i komunikatach o wyjątkach, czyniąc je bardziej czytelnymi i mniej podatnymi na błędy.

Logger.Log($"Error: The property '{nameof(MyClass.MyProperty)}' is out of range.");
Logger.Log($"Error: The property '{nameof(MyClass.MyProperty)}' is out of range.");
Logger.Log($"Error: The property '{NameOf([MyClass].MyProperty)}' is out of range.")
$vbLabelText   $csharpLabel

Przykład

W tym przykładzie utworzymy prostą klasę reprezentującą osobę i użyjemy operatora nameof w celu usprawnienia logowania i komunikatów o błędach.

using System;

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    // Method that displays the full name of the person
    public void DisplayFullName()
    {
        if (string.IsNullOrEmpty(FirstName) || string.IsNullOrEmpty(LastName))
        {
            LogError($"Invalid name: {nameof(FirstName)} or {nameof(LastName)} is missing.");
        }
        else
        {
            Console.WriteLine($"Full Name: {FirstName} {LastName}");
        }
    }

    // Custom error logging method that highlights errors
    private void LogError(string errorMessage)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine($"Error: {errorMessage}");
        Console.ResetColor();
    }
}

class Program
{
    static void Main()
    {
        // Create an instance of the Person class
        Person person = new Person();

        // Attempt to display the full name without setting the properties
        person.DisplayFullName();

        // Set the properties and display the full name again
        person.FirstName = "John";
        person.LastName = "Doe";
        person.DisplayFullName();
    }
}
using System;

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    // Method that displays the full name of the person
    public void DisplayFullName()
    {
        if (string.IsNullOrEmpty(FirstName) || string.IsNullOrEmpty(LastName))
        {
            LogError($"Invalid name: {nameof(FirstName)} or {nameof(LastName)} is missing.");
        }
        else
        {
            Console.WriteLine($"Full Name: {FirstName} {LastName}");
        }
    }

    // Custom error logging method that highlights errors
    private void LogError(string errorMessage)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine($"Error: {errorMessage}");
        Console.ResetColor();
    }
}

class Program
{
    static void Main()
    {
        // Create an instance of the Person class
        Person person = new Person();

        // Attempt to display the full name without setting the properties
        person.DisplayFullName();

        // Set the properties and display the full name again
        person.FirstName = "John";
        person.LastName = "Doe";
        person.DisplayFullName();
    }
}
Imports System

Friend Class Person
	Public Property FirstName() As String
	Public Property LastName() As String

	' Method that displays the full name of the person
	Public Sub DisplayFullName()
		If String.IsNullOrEmpty(FirstName) OrElse String.IsNullOrEmpty(LastName) Then
			LogError($"Invalid name: {NameOf(FirstName)} or {NameOf(LastName)} is missing.")
		Else
			Console.WriteLine($"Full Name: {FirstName} {LastName}")
		End If
	End Sub

	' Custom error logging method that highlights errors
	Private Sub LogError(ByVal errorMessage As String)
		Console.ForegroundColor = ConsoleColor.Red
		Console.WriteLine($"Error: {errorMessage}")
		Console.ResetColor()
	End Sub
End Class

Friend Class Program
	Shared Sub Main()
		' Create an instance of the Person class
		Dim person As New Person()

		' Attempt to display the full name without setting the properties
		person.DisplayFullName()

		' Set the properties and display the full name again
		person.FirstName = "John"
		person.LastName = "Doe"
		person.DisplayFullName()
	End Sub
End Class
$vbLabelText   $csharpLabel

Wyjaśnienie

  1. Mamy klasę Person z właściwościami FirstName i LastName oraz metodą DisplayFullName, która sprawdza, czy obie właściwości są ustawione, zanim wyświetli pełną nazwę.
  2. W metodzie DisplayFullName używamy nameof(FirstName) i nameof(LastName), aby odwołać się do nazw właściwości jako literałów łańcuchowych. Poprawia to czytelność kodu i gwarantuje, że w przypadku zmiany nazw właściwości zarówno definicja właściwości, jak i odpowiadający jej komunikat o błędzie zostaną automatycznie zaktualizowane podczas kompilacji.
  3. Metoda LogError wykorzystuje nameof do dynamicznego umieszczenia nazwy właściwości w komunikacie o błędzie.
  4. W metodzie Main tworzymy instancję klasy Person, próbujemy wyświetlić pełną nazwę bez ustawiania właściwości, a następnie ustawiamy właściwości i ponownie wyświetlamy pełną nazwę.

Po uruchomieniu tego programu zobaczysz, że komunikat o błędzie dynamicznie uwzględnia nazwy właściwości, zapewniając więcej kontekstu i ułatwiając identyfikację brakującej właściwości.

Ten przykład pokazuje, w jaki sposób operator nameof poprawia łatwość utrzymania kodu poprzez automatyczną aktualizację odwołań w przypadku zmiany nazw właściwości oraz wzbogaca komunikaty o błędach o bardziej szczegółowe informacje podczas tworzenia oprogramowania.

Przedstawiamy IronPDF

IronPDF dla C#.NET to biblioteka PDF firmy Iron Software, która może służyć jako generator i czytnik plików PDF. Poniżej przedstawiamy podstawowe funkcje. Więcej informacji można znaleźć w dokumentacji.

Wyróżniającą cechą IronPDF jest możliwość konwersji plików HTML do formatu PDF z zachowaniem układu i stylów. Generuje pliki PDF na podstawie treści internetowych, dzięki czemu świetnie nadaje się do tworzenia raportów, faktur i dokumentacji. Pliki HTML, adresy URL i ciągi znaków HTML można płynnie konwertować do formatu PDF.

using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
using IronPdf;

class Program
{
    static void Main(string[] args)
    {
        var renderer = new ChromePdfRenderer();

        // 1. Convert HTML String to PDF
        var htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>";
        var pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent);
        pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf");

        // 2. Convert HTML File to PDF
        var htmlFilePath = "path_to_your_html_file.html"; // Specify the path to your HTML file
        var pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath);
        pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf");

        // 3. Convert URL to PDF
        var url = "http://ironpdf.com"; // Specify the URL
        var pdfFromUrl = renderer.RenderUrlAsPdf(url);
        pdfFromUrl.SaveAs("URLToPDF.pdf");
    }
}
Imports IronPdf

Friend Class Program
	Shared Sub Main(ByVal args() As String)
		Dim renderer = New ChromePdfRenderer()

		' 1. Convert HTML String to PDF
		Dim htmlContent = "<h1>Hello, IronPDF!</h1><p>This is a PDF from an HTML string.</p>"
		Dim pdfFromHtmlString = renderer.RenderHtmlAsPdf(htmlContent)
		pdfFromHtmlString.SaveAs("HTMLStringToPDF.pdf")

		' 2. Convert HTML File to PDF
		Dim htmlFilePath = "path_to_your_html_file.html" ' Specify the path to your HTML file
		Dim pdfFromHtmlFile = renderer.RenderHtmlFileAsPdf(htmlFilePath)
		pdfFromHtmlFile.SaveAs("HTMLFileToPDF.pdf")

		' 3. Convert URL to PDF
		Dim url = "http://ironpdf.com" ' Specify the URL
		Dim pdfFromUrl = renderer.RenderUrlAsPdf(url)
		pdfFromUrl.SaveAs("URLToPDF.pdf")
	End Sub
End Class
$vbLabelText   $csharpLabel

Instalacja

IronPDF można zainstalować za pomocą konsoli menedżera pakietów NuGet lub menedżera pakietów Visual Studio.

dotnet add package IronPdf
dotnet add package IronPdf
SHELL

C# Nazwa (Jak to działa dla programistów): Rysunek 2 — Zainstaluj IronPDF za pomocą menedżera pakietów NuGet, wpisując

namespace OrderBy;

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public void DisplayFullName()
    {
        if (string.IsNullOrEmpty(FirstName) || string.IsNullOrEmpty(LastName))
        {
            LogError($"Invalid name: {nameof(FirstName)} or {nameof(LastName)} is missing.");
        }
        else
        {
            Console.WriteLine($"Full Name: {FirstName} {LastName}");
        }
    }

    public void PrintPdf()
    {
        Console.WriteLine("Generating PDF using IronPDF.");
        string content = $@"<!DOCTYPE html>
<html>
<body>
<h1>Hello, {FirstName}!</h1>
<p>First Name: {FirstName}</p>
<p>Last Name: {LastName}</p>
</body>
</html>";

        // Create a new PDF document
        var pdfDocument = new ChromePdfRenderer();
        pdfDocument.RenderHtmlAsPdf(content).SaveAs("person.pdf"); 
    }

    private void LogError(string errorMessage)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine($"Error: {errorMessage}");
        Console.ResetColor();
    }
}

class Program
{
    static void Main()
    {
        // Create an  instance of the Person class
        Person person = new Person();

        // Attempt to display the full name
        person.DisplayFullName();

        // Set the properties
        person.FirstName = "John";
        person.LastName = "Doe";

        // Display the full name again
        person.DisplayFullName();

        // Generate a PDF
        person.PrintPdf();
    }
}
namespace OrderBy;

class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }

    public void DisplayFullName()
    {
        if (string.IsNullOrEmpty(FirstName) || string.IsNullOrEmpty(LastName))
        {
            LogError($"Invalid name: {nameof(FirstName)} or {nameof(LastName)} is missing.");
        }
        else
        {
            Console.WriteLine($"Full Name: {FirstName} {LastName}");
        }
    }

    public void PrintPdf()
    {
        Console.WriteLine("Generating PDF using IronPDF.");
        string content = $@"<!DOCTYPE html>
<html>
<body>
<h1>Hello, {FirstName}!</h1>
<p>First Name: {FirstName}</p>
<p>Last Name: {LastName}</p>
</body>
</html>";

        // Create a new PDF document
        var pdfDocument = new ChromePdfRenderer();
        pdfDocument.RenderHtmlAsPdf(content).SaveAs("person.pdf"); 
    }

    private void LogError(string errorMessage)
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine($"Error: {errorMessage}");
        Console.ResetColor();
    }
}

class Program
{
    static void Main()
    {
        // Create an  instance of the Person class
        Person person = new Person();

        // Attempt to display the full name
        person.DisplayFullName();

        // Set the properties
        person.FirstName = "John";
        person.LastName = "Doe";

        // Display the full name again
        person.DisplayFullName();

        // Generate a PDF
        person.PrintPdf();
    }
}
Namespace OrderBy

	Friend Class Person
		Public Property FirstName() As String
		Public Property LastName() As String

		Public Sub DisplayFullName()
			If String.IsNullOrEmpty(FirstName) OrElse String.IsNullOrEmpty(LastName) Then
				LogError($"Invalid name: {NameOf(FirstName)} or {NameOf(LastName)} is missing.")
			Else
				Console.WriteLine($"Full Name: {FirstName} {LastName}")
			End If
		End Sub

		Public Sub PrintPdf()
			Console.WriteLine("Generating PDF using IronPDF.")
			Dim content As String = $"<!DOCTYPE html>
<html>
<body>
<h1>Hello, {FirstName}!</h1>
<p>First Name: {FirstName}</p>
<p>Last Name: {LastName}</p>
</body>
</html>"
	ignore ignore ignore ignore ignore ignore ignore var pdfDocument = New ChromePdfRenderer()
			pdfDocument.RenderHtmlAsPdf(content).SaveAs("person.pdf")
		End Sub

		Private Sub LogError(ByVal errorMessage As String)
			Console.ForegroundColor = ConsoleColor.Red
			Console.WriteLine($"Error: {errorMessage}")
			Console.ResetColor()
		End Sub
	End Class

	Friend Class Program
		Shared Sub Main()
			' Create an  instance of the Person class
			Dim person As New Person()

			' Attempt to display the full name
			person.DisplayFullName()

			' Set the properties
			person.FirstName = "John"
			person.LastName = "Doe"

			' Display the full name again
			person.DisplayFullName()

			' Generate a PDF
			person.PrintPdf()
		End Sub
	End Class
End Namespace
$vbLabelText   $csharpLabel

W tym przypadku IronPDF służy do generowania pliku PDF przy użyciu zmiennych lokalnych content i pdfDocument, co widać w metodzie PrintPdf.

Wynik

C# Nameof (Jak to działa dla programistów): Rysunek 3 – Wynik działania programu

Generowanie plików PDF

C# Nameof (Jak to działa dla programistów): Rysunek 4 – Wynik w formacie PDF

Licencjonowanie (dostępna bezpłatna wersja próbna)

Informacje na temat licencji można znaleźć w sekcji Informacje o Licencji Trial. Ten klucz należy umieścić w appsettings.json.

"IronPdf.LicenseKey": "your license key"

Podaj swój adres e-mail, aby otrzymać Licencję Trial.

Wnioski

Operator "nameof" w języku C# stał się podstawowym narzędziem dla programistów poszukujących czystszego, bezpieczniejszego i łatwiejszego w utrzymaniu kodu. Jego zdolność do poprawiania czytelności kodu, w połączeniu z bezpieczeństwem w czasie kompilacji i płynną obsługą refaktoryzacji, sprawia, że jest to niezbędne narzędzie w zestawie narzędzi programisty C#. Ponieważ społeczność programistów coraz chętniej korzysta z operatora "nameof", ma on szansę odegrać kluczową rolę w kształtowaniu przyszłości programowania w języku C#. IronPDF to przydatny pakiet NuGet, który można wykorzystać do szybkiego i łatwego generowania plików PDF.

Często Zadawane Pytania

Czym zajmuje się operator „nameof” w języku C#?

Operator „nameof” w języku C# zwraca nazwę elementu programu jako ciąg znaków, np. zmiennych, typów lub elementów składowych. Poprawia to czytelność i łatwość utrzymania kodu poprzez wyeliminowanie sztywno zakodowanych ciągów znaków.

W jaki sposób operator „nameof” może usprawnić refaktoryzację kodu?

Operator „nameof” ułatwia refaktoryzację kodu poprzez automatyczną aktualizację odwołań w przypadku zmiany nazw elementów, co zmniejsza liczbę błędów i poprawia wydajność procesów refaktoryzacji.

W jaki sposób operator „nameof” jest przydatny podczas debugowania?

Operator „nameof” usprawnia debugowanie, sprawiając, że komunikaty logowania i komunikaty o wyjątkach są bardziej opisowe i mniej podatne na błędy, ponieważ dynamicznie podaje rzeczywiste nazwy elementów programu.

Jakie jest praktyczne zastosowanie operatora „nameof” w języku C#?

Praktycznym zastosowaniem operatora „nameof” jest wykorzystanie go w logowaniu i obsłudze wyjątków w celu uczynienia komunikatów bardziej informacyjnymi poprzez uwzględnienie rzeczywistych nazw zmiennych lub metod.

Jak mogę przekonwertować zawartość HTML na pliki PDF w języku C#?

Możesz użyć IronPDF do konwersji treści HTML na pliki PDF w języku C#. IronPDF udostępnia metody konwersji ciągów znaków HTML, plików i adresów URL na dobrze sformatowane dokumenty PDF, idealne do raportów i dokumentacji.

Jakie są kroki instalacji biblioteki IronPDF?

Aby zainstalować IronPDF, należy użyć menedżera pakietów NuGet w Visual Studio, wykonując polecenie dotnet add package IronPdf w konsoli menedżera pakietów.

Czy IronPDF obsługuje konwersję HTML do PDF w przypadku złożonych układów stron?

Tak, IronPDF został zaprojektowany do konwersji HTML na PDF przy zachowaniu złożonych układów i stylów, zapewniając, że wynikowy plik PDF ściśle odpowiada oryginalnemu projektowi HTML.

Jakie są zalety korzystania z IronPDF do generowania plików PDF?

IronPDF umożliwia płynne generowanie plików PDF z treści HTML, obsługuje różne typy treści i zapewnia łatwe w użyciu API dla programistów, co czyni go wszechstronnym narzędziem do programowego tworzenia profesjonalnych dokumentów.

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