Samouczek: eksplorowanie pomysłów przy użyciu instrukcji najwyższego poziomu do kompilowania kodu podczas nauki
Z tego samouczka dowiesz się, jak wykonywać następujące czynności:
- Poznaj reguły dotyczące korzystania z instrukcji najwyższego poziomu.
- Używanie instrukcji najwyższego poziomu do eksplorowania algorytmów.
- Refaktoryzacja eksploracji składników wielokrotnego użytku.
Wymagania wstępne
Musisz skonfigurować maszynę do uruchamiania platformy .NET 6, która obejmuje kompilator języka C# 10. Kompilator języka C# 10 jest dostępny od wersji Visual Studio 2022 lub .NET 6 SDK.
W tym samouczku założono, że znasz języki C# i .NET, w tym program Visual Studio lub interfejs wiersza polecenia platformy .NET.
Rozpocznij eksplorację
Instrukcje najwyższego poziomu umożliwiają uniknięcie dodatkowej ceremonii wymaganej przez umieszczenie punktu wejścia programu w metodzie statycznej w klasie. Typowy punkt wyjścia dla nowej aplikacji konsolowej wygląda następująco:
using System;
namespace Application
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}
Powyższy kod jest wynikiem uruchomienia dotnet new console
polecenia i utworzenia nowej aplikacji konsolowej. Te 11 wierszy zawierają tylko jeden wiersz kodu wykonywalnego. Ten program można uprościć za pomocą nowej funkcji instrukcji najwyższego poziomu. Umożliwia to usunięcie wszystkich, ale dwóch wierszy w tym programie:
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
Ważne
Szablony języka C# dla platformy .NET 6 używają instrukcji najwyższego poziomu. Aplikacja może nie być zgodna z kodem w tym artykule, jeśli został już uaktualniony do platformy .NET 6. Aby uzyskać więcej informacji, zobacz artykuł dotyczący nowych szablonów języka C# generowania instrukcji najwyższego poziomu
Zestaw SDK platformy .NET 6 dodaje również zestaw niejawnych global using
dyrektyw dla projektów korzystających z następujących zestawów SDK:
- Microsoft.NET.Sdk
- Microsoft.NET.Sdk.Web
- Microsoft.NET.Sdk.Worker
Te niejawne global using
dyrektywy obejmują najbardziej typowe przestrzenie nazw dla typu projektu.
Aby uzyskać więcej informacji, zobacz artykuł dotyczący niejawnych dyrektyw using
Ta funkcja upraszcza to, co jest potrzebne do rozpoczęcia eksplorowania nowych pomysłów. Instrukcje najwyższego poziomu można używać do obsługi scenariuszy skryptów lub do eksplorowania. Po zakończeniu pracy z podstawami możesz rozpocząć refaktoryzację kodu i utworzyć metody, klasy lub inne zestawy dla utworzonych składników wielokrotnego użytku. Instrukcje najwyższego poziomu umożliwiają szybkie eksperymentowanie i samouczki dla początkujących. Zapewniają one również płynną ścieżkę od eksperymentowania do pełnych programów.
Instrukcje najwyższego poziomu są wykonywane w kolejności, w której są wyświetlane w pliku. Instrukcje najwyższego poziomu mogą być używane tylko w jednym pliku źródłowym w aplikacji. Kompilator generuje błąd, jeśli używasz ich w więcej niż jednym pliku.
Tworzenie magicznej maszyny odpowiedzi platformy .NET
W tym samouczku skompilujmy aplikację konsolową, która odpowiada na pytanie "tak" lub "nie" z losową odpowiedzią. Utworzysz funkcjonalność krok po kroku. Możesz skupić się na zadaniu, a nie na ceremonii potrzebnej do struktury typowego programu. Następnie, gdy będziesz zadowolony z funkcji, możesz refaktoryzować aplikację zgodnie z potrzebami.
Dobrym punktem wyjścia jest napisanie pytania z powrotem do konsoli. Możesz zacząć od napisania następującego kodu:
Console.WriteLine(args);
Nie deklarujesz zmiennej args
. W przypadku pojedynczego pliku źródłowego zawierającego instrukcje args
najwyższego poziomu kompilator rozpoznaje argumenty wiersza polecenia. Typ args to string[]
, jak we wszystkich programach języka C#.
Kod można przetestować, uruchamiając następujące dotnet run
polecenie:
dotnet run -- Should I use top level statements in all my programs?
Argumenty po --
wierszu polecenia są przekazywane do programu. Możesz zobaczyć typ zmiennej args
, ponieważ jest to, co jest drukowane w konsoli:
System.String[]
Aby napisać pytanie w konsoli, należy wyliczyć argumenty i oddzielić je spacją. Zastąp wywołanie WriteLine
następującym kodem:
Console.WriteLine();
foreach(var s in args)
{
Console.Write(s);
Console.Write(' ');
}
Console.WriteLine();
Teraz po uruchomieniu programu poprawnie wyświetli ono pytanie jako ciąg argumentów.
Odpowiadanie przy użyciu odpowiedzi losowej
Po powtórzeniu pytania możesz dodać kod, aby wygenerować losową odpowiedź. Zacznij od dodania tablicy możliwych odpowiedzi:
string[] answers =
[
"It is certain.", "Reply hazy, try again.", "Don’t count on it.",
"It is decidedly so.", "Ask again later.", "My reply is no.",
"Without a doubt.", "Better not tell you now.", "My sources say no.",
"Yes – definitely.", "Cannot predict now.", "Outlook not so good.",
"You may rely on it.", "Concentrate and ask again.", "Very doubtful.",
"As I see it, yes.",
"Most likely.",
"Outlook good.",
"Yes.",
"Signs point to yes.",
];
Ta tablica zawiera dziesięć odpowiedzi, które są twierdzące, pięć, które nie są zatwierdzające, i pięć, które są ujemne. Następnie dodaj następujący kod, aby wygenerować i wyświetlić losową odpowiedź z tablicy:
var index = new Random().Next(answers.Length - 1);
Console.WriteLine(answers[index]);
Możesz ponownie uruchomić aplikację, aby wyświetlić wyniki. Powinny zostać wyświetlone dane wyjściowe podobne do następujących:
dotnet run -- Should I use top level statements in all my programs?
Should I use top level statements in all my programs?
Better not tell you now.
Ten kod odpowiada na pytania, ale dodajmy jeszcze jedną funkcję. Chcesz, aby aplikacja pytań symulowała myślenie o odpowiedzi. Możesz to zrobić, dodając trochę animacji ASCII i wstrzymując podczas pracy. Dodaj następujący kod po wierszu, który odzwierciedla pytanie:
for (int i = 0; i < 20; i++)
{
Console.Write("| -");
await Task.Delay(50);
Console.Write("\b\b\b");
Console.Write("/ \\");
await Task.Delay(50);
Console.Write("\b\b\b");
Console.Write("- |");
await Task.Delay(50);
Console.Write("\b\b\b");
Console.Write("\\ /");
await Task.Delay(50);
Console.Write("\b\b\b");
}
Console.WriteLine();
Należy również dodać instrukcję using
na początku pliku źródłowego:
using System.Threading.Tasks;
Instrukcje using
muszą być przed wszelkimi innymi instrukcjami w pliku. W przeciwnym razie jest to błąd kompilatora. Możesz ponownie uruchomić program i zobaczyć animację. To sprawia, że lepsze środowisko. Poeksperymentuj z długością opóźnienia, aby dopasować smak.
Powyższy kod tworzy zestaw wirujących wierszy oddzielonych spacją. Dodanie słowa kluczowego await
powoduje, że kompilator wygeneruje punkt wejścia programu jako metodę, która ma async
modyfikator, i zwraca element System.Threading.Tasks.Task. Ten program nie zwraca wartości, więc punkt wejścia programu zwraca Task
wartość . Jeśli program zwraca wartość całkowitą, należy dodać instrukcję return na końcu instrukcji najwyższego poziomu. Ta instrukcja return określa wartość całkowitą, która ma być zwracana. Jeśli instrukcje najwyższego poziomu zawierają await
wyrażenie, zwracany typ stanie się System.Threading.Tasks.Task<TResult>.
Refaktoryzacja na przyszłość
Twój program powinien wyglądać podobnie do następującego kodu:
Console.WriteLine();
foreach(var s in args)
{
Console.Write(s);
Console.Write(' ');
}
Console.WriteLine();
for (int i = 0; i < 20; i++)
{
Console.Write("| -");
await Task.Delay(50);
Console.Write("\b\b\b");
Console.Write("/ \\");
await Task.Delay(50);
Console.Write("\b\b\b");
Console.Write("- |");
await Task.Delay(50);
Console.Write("\b\b\b");
Console.Write("\\ /");
await Task.Delay(50);
Console.Write("\b\b\b");
}
Console.WriteLine();
string[] answers =
[
"It is certain.", "Reply hazy, try again.", "Don't count on it.",
"It is decidedly so.", "Ask again later.", "My reply is no.",
"Without a doubt.", "Better not tell you now.", "My sources say no.",
"Yes – definitely.", "Cannot predict now.", "Outlook not so good.",
"You may rely on it.", "Concentrate and ask again.", "Very doubtful.",
"As I see it, yes.",
"Most likely.",
"Outlook good.",
"Yes.",
"Signs point to yes.",
];
var index = new Random().Next(answers.Length - 1);
Console.WriteLine(answers[index]);
Powyższy kod jest rozsądny. To działa. Ale nie jest wielokrotnego użytku. Teraz, gdy aplikacja działa, nadszedł czas, aby ściągnąć części wielokrotnego użytku.
Jednym z kandydatów jest kod, który wyświetla animację oczekiwania. Ten fragment kodu może stać się metodą:
Możesz zacząć od utworzenia funkcji lokalnej w pliku. Zastąp bieżącą animację następującym kodem:
await ShowConsoleAnimation();
static async Task ShowConsoleAnimation()
{
for (int i = 0; i < 20; i++)
{
Console.Write("| -");
await Task.Delay(50);
Console.Write("\b\b\b");
Console.Write("/ \\");
await Task.Delay(50);
Console.Write("\b\b\b");
Console.Write("- |");
await Task.Delay(50);
Console.Write("\b\b\b");
Console.Write("\\ /");
await Task.Delay(50);
Console.Write("\b\b\b");
}
Console.WriteLine();
}
Powyższy kod tworzy funkcję lokalną wewnątrz metody main. To nadal nie jest wielokrotnego użytku. Dlatego wyodrębnij ten kod do klasy. Utwórz nowy plik o nazwie utilities.cs i dodaj następujący kod:
namespace MyNamespace
{
public static class Utilities
{
public static async Task ShowConsoleAnimation()
{
for (int i = 0; i < 20; i++)
{
Console.Write("| -");
await Task.Delay(50);
Console.Write("\b\b\b");
Console.Write("/ \\");
await Task.Delay(50);
Console.Write("\b\b\b");
Console.Write("- |");
await Task.Delay(50);
Console.Write("\b\b\b");
Console.Write("\\ /");
await Task.Delay(50);
Console.Write("\b\b\b");
}
Console.WriteLine();
}
}
}
Plik zawierający instrukcje najwyższego poziomu może również zawierać przestrzenie nazw i typy na końcu pliku po instrukcjach najwyższego poziomu. Jednak na potrzeby tego samouczka metoda animacji zostanie umieszczona w osobnym pliku, aby ułatwić jej wielokrotne użycie.
Na koniec możesz wyczyścić kod animacji, aby usunąć pewne duplikaty:
foreach (string s in animations)
{
Console.Write(s);
await Task.Delay(50);
Console.Write("\b\b\b");
}
Teraz masz kompletną aplikację i refaktoryzujesz części wielokrotnego użytku do późniejszego użycia. Nową metodę narzędzia można wywołać z instrukcji najwyższego poziomu, jak pokazano poniżej w gotowej wersji głównego programu:
using MyNamespace;
Console.WriteLine();
foreach(var s in args)
{
Console.Write(s);
Console.Write(' ');
}
Console.WriteLine();
await Utilities.ShowConsoleAnimation();
string[] answers =
[
"It is certain.", "Reply hazy, try again.", "Don’t count on it.",
"It is decidedly so.", "Ask again later.", "My reply is no.",
"Without a doubt.", "Better not tell you now.", "My sources say no.",
"Yes – definitely.", "Cannot predict now.", "Outlook not so good.",
"You may rely on it.", "Concentrate and ask again.", "Very doubtful.",
"As I see it, yes.",
"Most likely.",
"Outlook good.",
"Yes.",
"Signs point to yes.",
];
var index = new Random().Next(answers.Length - 1);
Console.WriteLine(answers[index]);
W poprzednim przykładzie dodano wywołanie metody Utilities.ShowConsoleAnimation
i dodano dodatkową using
instrukcję .
Podsumowanie
Instrukcje najwyższego poziomu ułatwiają tworzenie prostych programów do użycia w celu eksplorowania nowych algorytmów. Możesz eksperymentować z algorytmami, próbując próbować różnych fragmentów kodu. Gdy już wiesz, co działa, możesz refaktoryzować kod, aby był bardziej konserwowalny.
Instrukcje najwyższego poziomu upraszczają programy oparte na aplikacjach konsolowych. Obejmują one funkcje platformy Azure, akcje GitHub i inne małe narzędzia. Aby uzyskać więcej informacji, zobacz Instrukcje najwyższego poziomu (Przewodnik programowania w języku C#).