Aracılığıyla paylaş


Öğretici: Dosya tabanlı C# programları oluşturma

Dosya tabanlı uygulamalar, ilgili proje (*.cs) dosyası olmadan oluşturulan ve çalıştırılan tek *.csproj bir dosyanın içinde yer alan programlardır. Dosya tabanlı uygulamalar, daha az karmaşıklıkları olduğundan C# öğrenmek için idealdir: Programın tamamı tek bir dosyada depolanır. Dosya tabanlı uygulamalar, komut satırı yardımcı programları oluşturmak için de kullanışlıdır. Unix platformlarında dosya tabanlı uygulamalar (shebang) #! kullanılarak çalıştırılabilir. Bu eğitimde, siz:

  • Dosya tabanlı bir program oluşturun.
  • Unix shebang (#!) desteği ekleyin.
  • Komut satırı bağımsız değişkenlerini okuyun.
  • Standart girişi işleme.
  • ASCII resim çıkışı yazın.
  • komut satırı bağımsız değişkenlerini işleme.
  • Ayrıştırılmış komut satırı sonuçlarını kullanın.
  • Son uygulamayı test edin.

Metni ASCII resmi olarak yazan dosya tabanlı bir program oluşturursunuz. Uygulama tek bir dosyada yer alır, bazı temel özellikleri uygulayan NuGet paketlerini kullanır.

Önkoşullar

Dosya tabanlı program oluşturma

  1. Visual Studio Code'u açın ve adlı AsciiArt.csyeni bir dosya oluşturun. Aşağıdaki metni girin:

    Console.WriteLine("Hello, world!");
    
  2. Dosyayı kaydedin. Ardından Visual Studio Code'da tümleşik terminali açın ve şunu yazın:

    dotnet run AsciiArt.cs
    

Bu programı ilk kez çalıştırdığınızda dotnet , konak yürütülebilir dosyayı kaynak dosyanızdan oluşturur, derleme yapıtlarını geçici bir klasörde depolar ve ardından oluşturulan yürütülebilir dosyayı çalıştırır. Bu deneyimi yeniden yazarak dotnet run AsciiArt.cs doğrulayabilirsiniz. Bu kez, dotnet ana bilgisayar yürütülebilir dosyanın geçerli olduğunu belirler ve yürütülebilir dosyayı yeniden derlemeden çalıştırır. Herhangi bir derleme çıktısı görmezsiniz.

Yukarıdaki adımlarda dosya tabanlı uygulamaların betik dosyası olmadığını gösterilmektedir. Bunlar, geçici bir klasörde oluşturulan bir proje dosyası kullanılarak oluşturulan C# kaynak dosyalarıdır. Programı oluştururken görüntülenen çıkış satırlarından biri şuna benzer olmalıdır (Windows'da):

AsciiArt succeeded (7.3s) → AppData\Local\Temp\dotnet\runfile\AsciiArt-85c58ae0cd68371711f06f297fa0d7891d0de82afde04d8c64d5f910ddc04ddc\bin\debug\AsciiArt.dll

Unix platformlarında çıkış klasörü şuna benzer:

AsciiArt succeeded (7.3s) → Library/Application Support/dotnet/runfile/AsciiArt-85c58ae0cd68371711f06f297fa0d7891d0de82afde04d8c64d5f910ddc04ddc/bin/debug/AsciiArt.dll

Bu çıkış, geçici dosyaların ve derleme çıkışlarının nereye yerleştirildiğini size bildirir. Bu öğretici boyunca, kaynak dosyayı her düzenlediğinizde, dotnet konak yürütülebilir dosyayı çalışmadan önce güncelleştirir.

Dosya tabanlı uygulamalar normal C# programlarıdır. Tek sınırlama, bunların tek bir kaynak dosyada yazılması gerektiğidir. Giriş noktası olarak üst düzey deyimleri veya klasik Main bir yöntemi kullanabilirsiniz. Herhangi bir türü bildirebilirsiniz: sınıflar, arabirimler ve yapılar. Dosya tabanlı bir programdaki algoritmaları, herhangi bir C# programında yaptığınız gibi yapılandırabilirsiniz. Kodunuzu düzenlemek için birden çok ad alanı bile bildirebilirsiniz. Dosya tabanlı bir programın tek bir dosya için fazla büyüdüğünü fark ederseniz, bunu proje tabanlı bir programa dönüştürebilir ve kaynağı birden çok dosyaya bölebilirsiniz. Dosya tabanlı uygulamalar harika bir prototip oluşturma aracıdır. Kavramları kanıtlamak ve algoritmalar oluşturmak için minimum ek yükle denemeler yapmaya başlayabilirsiniz.

Unix shebang (#!) desteği

Uyarı

Yönergeler için #! destek yalnızca unix platformlarında geçerlidir. Windows'un bir C# programını doğrudan yürütmesi için benzer bir yönerge yoktur. Windows'da, komut satırında kullanmanız dotnet run gerekir.

Unix'te, dosya tabanlı uygulamaları doğrudan çalıştırabilir ve komut satırına dotnet runyerine kaynak dosya adını yazabilirsiniz. İki değişiklik yapmanız gerekir:

  1. Kaynak dosyada yürütme izinlerini ayarlayın:

    chmod +x AsciiArt.cs
    
  2. Dosyanın ilk satırı olarak shebang (#!) yönergesi AsciiArt.cs ekleyin:

    #!/usr/local/share/dotnet/dotnet run
    

konumu dotnet farklı unix yüklemelerinde farklı olabilir. which dotnet komutunu ortamınızdaki dotnet konağı bulmak için kullanın.

Alternatif olarak, PATH ortam değişkeninden dotnet yolunu otomatik olarak çözümlemek için kullanabilirsiniz #!/usr/bin/env dotnet :

#!/usr/bin/env dotnet

Bu iki değişikliği yaptıktan sonra, programı doğrudan komut satırından çalıştırabilirsiniz:

./AsciiArt.cs

İsterseniz, bunun yerine yazabilmeniz ./AsciiArt için uzantıyı kaldırabilirsiniz. Windows kullanıyor olsanız bile öğesini kaynak dosyanıza ekleyebilirsiniz #! . Windows komut satırı desteklemez #!, ancak C# derleyicisi tüm platformlardaki dosya tabanlı uygulamalarda bu yönergeye izin verir.

Komut satırı bağımsız değişkenlerini okuma

Şimdi, komut satırındaki tüm bağımsız değişkenleri çıktıya yazın.

  1. öğesinin geçerli içeriğini AsciiArt.cs aşağıdaki kodla değiştirin:

    if (args.Length > 0)
    {
        string message = string.Join(' ', args);
        Console.WriteLine(message);
    }
    
  2. Aşağıdaki komutu yazarak bu sürümü çalıştırabilirsiniz:

    dotnet run AsciiArt.cs -- This is the command line.
    

    seçeneği, -- aşağıdaki tüm komut bağımsız değişkenlerinin AsciiArt programına geçirilmesi gerektiğini gösterir. Bağımsız değişkenler This is the command line. bir dize dizisi olarak geçirilir ve burada her dize bir sözcük olur: This, is, the, commandve line..

Bu sürüm şu yeni kavramları gösterir:

  • Komut satırı bağımsız değişkenleri, önceden tanımlanmış değişkeni argskullanılarak programa geçirilir. args değişkeni bir dize dizisidir: string[]. uzunluğu args 0 ise, bu hiçbir bağımsız değişken sağlanmadı anlamına gelir. Aksi takdirde, bağımsız değişken listesindeki her sözcük dizideki karşılık gelen girişte depolanır.
  • yöntemi, string.Join belirtilen ayırıcı ile birden çok dizeyi tek bir dizede birleştirir. Bu durumda, ayırıcı tek bir boşluk olur.
  • Console.WriteLine dizesini standart çıkış konsoluna yazar ve ardından yeni bir satır yazar.

Standart girişi işleme

Bu, komut satırı bağımsız değişkenlerini doğru işler. Şimdi, komut satırı bağımsız değişkenleri yerine standart girişten (stdin) okuma girişini işlemek için kodu ekleyin.

  1. Yukarıdaki koda eklediğiniz deyimine else aşağıdaki if yan tümceyi ekleyin:

    else
    {
        while (Console.ReadLine() is string line && line.Length > 0)
        {
            Console.WriteLine(line);
        }
    }
    

    Yukarıdaki kod, boş bir satır veya null okunana kadar konsol girişini okur. (Yöntem, Console.ReadLine giriş akışı null yazarak kapatılırsa döndürür.)

  2. Aynı klasörde yeni bir metin dosyası oluşturarak standart girişi okumayı test edin. Dosyayı input.txt adlandırın ve aşağıdaki satırları ekleyin:

    Hello from ...
    dotnet!
    
    You can create
    file-based apps
    in .NET 10 and
    C# 14
    
    Have fun writing
    useful utilities
    

    ASCII resmi kullanmak üzere özelliği eklediğinizde çizgilerin doğru biçimlendirildiğinden kısa tutun.

  3. Programı yeniden çalıştırın.

    Bash ile:

    cat input.txt | dotnet run AsciiArt.cs
    

    Veya PowerShell ile:

    Get-Content input.txt | dotnet run AsciiArt.cs
    

Artık programınız komut satırı bağımsız değişkenlerini veya standart girişi kabul edebilir.

ASCII Resim çıkışı yazma

Ardından, ASCII resmi olan Colorful.Console'ı destekleyen bir paket ekleyin. Dosya tabanlı bir programa paket eklemek için yönergesini #:package kullanırsınız.

  1. AsciiArt.cs dosyanızda yönergeden sonra aşağıdaki yönergeyi #! ekleyin:

    #:package Colorful.Console@1.2.15
    

    Önemli

    Sürüm 1.2.15 , bu öğreticinin son güncelleştirildiğinde paketin Colorful.Console en son sürümüdür. En son güvenlik düzeltmelerini içeren bir paket sürümü kullandığınızdan emin olmak için paketin NuGet sayfasına bakın.

  2. Bunun yerine yöntemini kullanmak için çağıran Console.WriteLineColorful.Console.WriteAscii satırları değiştirin:

    async Task WriteAsciiArt(AsciiMessageOptions options)
    {
        foreach (string message in options.Messages)
        {
            Colorful.Console.WriteAscii(message);
            await Task.Delay(options.Delay);
        }
    }
    
  3. Programı çalıştırdığınızda, yankılanan metin yerine ASCII resim çıktısı görürsünüz.

İşlem komutu seçenekleri

Şimdi komut satırı ayrıştırma ekleyelim. Geçerli sürüm her sözcüğü farklı bir çıkış satırı olarak yazar. Eklediğiniz komut satırı bağımsız değişkenleri iki özelliği destekler:

  1. Tek satırda yazılması gereken birden çok sözcüğü tırnak içine alın:

    AsciiArt.cs "This is line one" "This is another line" "This is the last line"
    
  2. --delay Her satır arasında duraklatma seçeneği ekleyin:

    AsciiArt.cs --delay 1000
    

Kullanıcılar her iki bağımsız değişkeni birlikte kullanabilmelidir.

Çoğu komut satırı uygulamasının seçenekleri, komutları ve kullanıcı girişini etkili bir şekilde işlemek için komut satırı bağımsız değişkenlerini ayrıştırmaları gerekir. KitaplıkSystem.CommandLine komutları, alt komutları, seçenekleri ve bağımsız değişkenleri işlemek için kapsamlı özellikler seçerek komut satırı girişini ayrıştırma mekaniği yerine uygulamanızın yaptıklarına odaklanmanızı sağlar.

Kitaplık System.CommandLine çeşitli önemli avantajlar sunar:

  • Otomatik yardım metni oluşturma ve doğrulama.
  • POSIX ve Windows komut satırı kuralları desteği.
  • Yerleşik sekme tamamlama özellikleri.
  • Uygulamalar arasında tutarlı ayrıştırma davranışı.
  1. System.CommandLine Paketi ekleyin. Bu yönergeyi mevcut paket yönergesinin arkasına ekleyin:

    #:package System.CommandLine@2.0.0
    

    Önemli

    2.0.0 Sürüm, bu öğreticinin son güncelleştirildiği en son sürümdü. Daha yeni bir sürüm varsa en son güvenlik paketlerine sahip olduğunuzdan emin olmak için en son sürümü kullanın. En son güvenlik düzeltmelerini içeren bir paket sürümü kullandığınızdan emin olmak için paketin NuGet sayfasına bakın.

  2. Dosyanızın en üstüne gerekli using deyimlerini ekleyin (ve #! yönergelerinden #:package sonra):

    using System.CommandLine;
    using System.CommandLine.Parsing;
    
  3. Gecikme seçeneğini ve iletiler bağımsız değişkenini tanımlayın. Komut satırı seçeneğini ve bağımsız değişkenini CommandLine.Option temsil eden ve CommandLine.Argument nesnelerini oluşturmak için aşağıdaki kodu ekleyin:

    Option<int> delayOption = new("--delay")
    {
        Description = "Delay between lines, specified as milliseconds.",
        DefaultValueFactory = parseResult => 100
    };
    
    Argument<string[]> messagesArgument = new("Messages")
    {
        Description = "Text to render."
    };
    

    Komut satırı uygulamalarında seçenekler genellikle (çift tire) ile -- başlar ve bağımsız değişkenleri kabul edebilir. seçeneği, --delay gecikmeyi milisaniye cinsinden belirten bir tamsayı bağımsız değişkenini kabul eder. , messagesArgument seçeneklerden sonra kalan belirteçlerin nasıl metin olarak ayrıştırılmış olduğunu tanımlar. Her belirteç dizide ayrı bir dizeye dönüşür, ancak metin tek bir belirteçte birden çok sözcük içerecek şekilde alıntılanabilir. Örneğin, "This is one message" tek bir belirteç olurken This is four tokens dört ayrı belirteç olur.

    Yukarıdaki kod, seçenek için --delay bağımsız değişken türünü tanımlar ve bağımsız değişkenlerin bir değer dizisi string olduğunu tanımlar. Bu uygulamanın tek bir komutu vardır, bu nedenle kök komutunu kullanırsınız.

  4. Bir kök komutu oluşturun ve bunu seçenek ve bağımsız değişkenle yapılandırın. Bağımsız değişkeni ve seçeneği kök komutuna ekleyin:

    RootCommand rootCommand = new("Ascii Art file-based program sample");
    
    rootCommand.Options.Add(delayOption);
    rootCommand.Arguments.Add(messagesArgument);
    
  5. Komut satırı bağımsız değişkenlerini ayrıştırmak ve hataları işlemek için kodu ekleyin. Bu kod komut satırı bağımsız değişkenlerini doğrular ve ayrıştırılmış bağımsız değişkenleri nesnesinde System.CommandLine.ParseResult depolar:

    ParseResult result = rootCommand.Parse(args);
    foreach (ParseError parseError in result.Errors)
    {
        Console.Error.WriteLine(parseError.Message);
    }
    if (result.Errors.Count > 0)
    {
        return 1;
    }
    

Yukarıdaki kod tüm komut satırı bağımsız değişkenlerini doğrular. Doğrulama başarısız olursa, hatalar konsola yazılır ve uygulamadan çıkar.

Ayrıştırılmış komut satırı sonuçlarını kullanma

Şimdi ayrıştırılmış seçenekleri kullanmak için uygulamayı tamamlayın ve çıktıyı yazın. İlk olarak, ayrıştırılmış seçenekleri tutmak için bir kayıt tanımlayın. Dosya tabanlı uygulamalar, kayıtlar ve sınıflar gibi tür bildirimleri içerebilir. Tüm üst düzey deyimlerden ve yerel işlevlerden sonra olmalıdır.

  1. İletileri ve gecikme seçeneği değerini depolamak için bir record bildirim ekleyin:

    public record AsciiMessageOptions(string[] Messages, int Delay);
    
  2. Kayıt bildiriminden önce aşağıdaki yerel işlevi ekleyin. Bu yöntem hem komut satırı bağımsız değişkenlerini hem de standart girişi işler ve yeni bir kayıt örneği döndürür:

    async Task<AsciiMessageOptions> ProcessParseResults(ParseResult result)
    {
        int delay = result.GetValue(delayOption);
        List<string> messages = [.. result.GetValue(messagesArgument) ?? Array.Empty<string>()];
    
        if (messages.Count == 0)
        {
            while (Console.ReadLine() is string line && line.Length > 0)
            {
                Colorful.Console.WriteAscii(line);
                await Task.Delay(delay);
            }
        }
        return new([.. messages], delay);
    }
    
  3. Belirtilen gecikme süresiyle ASCII resmi yazmak için yerel bir işlev oluşturun. Bu işlev, kayıttaki her iletiyi, her ileti arasında belirtilen gecikme süresiyle yazar:

    async Task WriteAsciiArt(AsciiMessageOptions options)
    {
        foreach (string message in options.Messages)
        {
            Colorful.Console.WriteAscii(message);
            await Task.Delay(options.Delay);
        }
    }
    
  4. if Daha önce yazdığınız yan tümcesini, komut satırı bağımsız değişkenlerini işleyen ve çıkışı yazan aşağıdaki kodla değiştirin:

    var parsedArgs = await ProcessParseResults(result);
    
    await WriteAsciiArt(parsedArgs);
    return 0;
    

Ayrıştırılmış komut satırı seçeneklerine ve bağımsız değişkenlerine yapı sağlayan bir record tür oluşturdunuz. Yeni yerel işlevler kaydın bir örneğini oluşturur ve ASCII resim çıkışını yazmak için kaydı kullanır.

Son uygulamayı test edin

Birkaç farklı komut çalıştırarak uygulamayı test edin. Sorun yaşıyorsanız, derlediğinizle karşılaştırabileceğiniz tamamlanmış örnek aşağıda verilmiştir:

#!/usr/local/share/dotnet/dotnet run

#:package Colorful.Console@1.2.15
#:package System.CommandLine@2.0.0

using System.CommandLine;
using System.CommandLine.Parsing;

Option<int> delayOption = new("--delay")
{
    Description = "Delay between lines, specified as milliseconds.",
    DefaultValueFactory = parseResult => 100
};

Argument<string[]> messagesArgument = new("Messages")
{
    Description = "Text to render."
};

RootCommand rootCommand = new("Ascii Art file-based program sample");

rootCommand.Options.Add(delayOption);
rootCommand.Arguments.Add(messagesArgument);

ParseResult result = rootCommand.Parse(args);
foreach (ParseError parseError in result.Errors)
{
    Console.Error.WriteLine(parseError.Message);
}
if (result.Errors.Count > 0)
{
    return 1;
}

var parsedArgs = await ProcessParseResults(result);

await WriteAsciiArt(parsedArgs);
return 0;

async Task<AsciiMessageOptions> ProcessParseResults(ParseResult result)
{
    int delay = result.GetValue(delayOption);
    List<string> messages = [.. result.GetValue(messagesArgument) ?? Array.Empty<string>()];

    if (messages.Count == 0)
    {
        while (Console.ReadLine() is string line && line.Length > 0)
        {
            // <WriteAscii>
            Colorful.Console.WriteAscii(line);
            // </WriteAscii>
            await Task.Delay(delay);
        }
    }
    return new([.. messages], delay);
}

async Task WriteAsciiArt(AsciiMessageOptions options)
{
    foreach (string message in options.Messages)
    {
        Colorful.Console.WriteAscii(message);
        await Task.Delay(options.Delay);
    }
}

public record AsciiMessageOptions(string[] Messages, int Delay);

Bu öğreticide, programı tek bir C# dosyasında derlediğiniz dosya tabanlı bir program oluşturmayı öğrendiniz. Bu programlar proje dosyası kullanmaz ve unix sistemlerde yönergesini #! kullanabilir. Öğrenciler , çevrimiçi öğreticilerimizi denedikten sonra ve daha büyük proje tabanlı uygulamalar oluşturmadan önce bu programları oluşturabilir. Dosya tabanlı uygulamalar, komut satırı yardımcı programları için de harika bir platformdır.