Projesiz C#, .NET 10 SDK ile tek bir .cs dosyasını ayrı bir .csproj oluşturmadan derleyip çalıştırmayı sağlar. Microsoft bu yaklaşımı file-based apps olarak adlandırıyor. Küçük CLI araçlarında ve prototiplerde başlangıcı sadeleştirir; büyüyen uygulamalarda ise klasik proje yapısının sağladığı organizasyon hâlâ değerlidir.

Akış şemasındaki #package ve #sdk etiketlerinin C# dosyasında geçerli karşılığı #:package ve #:sdk biçimindedir. SDK kaynak kodu derler; ilk çalıştırmada restore ve build maliyetini hesaba katın.
1. Projesiz C# ve klasik proje akışı
1.1 Eskiden Nasıldı?
- Klasik .NET CLI akışında dotnet new console ile proje oluşturur, bağımlılık ve derleme ayarlarını .csproj üzerinden yönetirsiniz. C# Interactive gibi başka deneme araçları da vardır; file-based app bu proje akışına ek bir seçenektir.
- Tüm bağımlılıklar, paketler ve derleme ayarları .csproj dosyasında tutulurdu.
- File-based app bir yorumlanan script değildir. SDK arka planda proje yapılandırmasını oluşturup normal C# programını derler; sizin ayrı bir .csproj yazmanız gerekmez.
1.2 .NET 10 ile Neler Değişti?
- Artık tek bir .cs dosyasıyla, projesiz doğrudan geliştirme mümkün.
- Dosyanın başındaki #:package ve #:sdk direktifleri, paket referanslarını ve MSBuild SDK türünü belirtir. #:sdk, kurulu .NET SDK sürümünü seçmez; bu seçim için global.json ve SDK kurulumunu kullanırsınız.
- Terminalde dotnet run –file dosya.cs ile çalıştırın. Aynı klasörde .csproj varsa –file kullanmadan dotnet run dosya.cs yazmak mevcut projeyi çalıştırıp dosya adını argüman olarak iletebilir.

2. #:package ve #:sdk Direktifleriyle Bağımlılık Yönetimi
2.1 #:package Kullanımı
File-based app dosyasının başında paket referanslarını şöyle tanımlayabilirsiniz:
#:package Newtonsoft.Json@13.0.4
#:package Dapper@2.0.123
#:property PublishAot=false
using Newtonsoft.Json;
using Dapper;
Console.WriteLine(JsonConvert.SerializeObject(new { Message = "Merhaba" }));
- Çoklu paket desteği: Dilediğin kadar farklı paketi başa ekleyebilirsin.
- Sürüm belirtme: Paket adı ile sürüm arasına @ koyun; örneğin #:package Newtonsoft.Json@13.0.4. Merkezi paket yönetimi yoksa sürümü belirtin. @* kullanmak sürümü sabitlemez; örneklerin tekrar üretilebilirliğini azaltır.
2.2 #:sdk Direktifi
Web SDK türünü seçip küçük bir endpoint oluşturmak için:
#:sdk Microsoft.NET.Sdk.Web
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Merhaba");
app.Run();
- Varsayılan SDK Microsoft.NET.Sdk’dir; web uygulaması için Microsoft.NET.Sdk.Web seçebilirsiniz. TargetFramework gibi MSBuild ayarlarını #:property ile belirtin. .NET SDK sürümünü bununla karıştırmayın.
3. Projesiz C# kod örnekleri
3.1 Hızlı Komut Satırı Araçları
Tek dosyada, mevcut klasördeki PNG dosyalarını bir ZIP arşivine eklemek:
using System.IO.Compression;
var output = "tum_resimler.zip";
if (File.Exists(output))
{
Console.Error.WriteLine(
"Arşiv zaten var; farklı ad seçin veya mevcut dosyayı inceleyin."
);
return 1;
}
var pngs = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.png");
using var archive = ZipFile.Open(output, ZipArchiveMode.Create);
foreach (var file in pngs)
archive.CreateEntryFromFile(file, Path.GetFileName(file));
Console.WriteLine("PNG dosyaları arşive eklendi.");
return 0;
3.2 Hızlı JSON İşleme ve API Tüketimi
#:package Newtonsoft.Json@13.0.4
#:property PublishAot=false
using Newtonsoft.Json.Linq;
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(15) };
try
{
var data = await client.GetStringAsync("https://randomuser.me/api/");
var user = JObject.Parse(data)["results"]?.FirstOrDefault()?["name"];
if (user?["first"] is null || user["last"] is null)
{
Console.Error.WriteLine("API yanıtında beklenen isim alanları yok.");
return 1;
}
Console.WriteLine($"İsim: {user["first"]} {user["last"]}");
return 0;
}
catch (Exception ex) when (ex is HttpRequestException or TaskCanceledException or Newtonsoft.Json.JsonException)
{
Console.Error.WriteLine($"API verisi alınamadı veya ayrıştırılamadı: {ex.Message}");
return 1;
}
3.3 CLI ile Mini Oyun veya Eğitim Scripti
Console.WriteLine("Bir sayı tahmin et (1-10):");
int dogru = Random.Shared.Next(1, 11);
if (
!int.TryParse(Console.ReadLine(), out int tahmin)
|| tahmin is < 1 or > 10
)
{
Console.Error.WriteLine("1 ile 10 arasında bir tam sayı girin.");
return 1;
}
Console.WriteLine(
tahmin == dogru ? "Doğru tahmin!" : $"Doğru cevap: {dogru}"
);
return 0;
3.4 Veritabanı Bağlantısı ve Kayıt İşlemleri
#:package System.Data.SQLite.Core@1.0.119
#:property PublishAot=false
using System.Data.SQLite;
using var conn = new SQLiteConnection("Data Source=demo.db");
conn.Open();
using (var create = new SQLiteCommand("CREATE TABLE IF NOT EXISTS notes (id INTEGER PRIMARY KEY, text TEXT)", conn))
create.ExecuteNonQuery();
using var insert = new SQLiteCommand("INSERT INTO notes (text) VALUES (@text)", conn);
insert.Parameters.AddWithValue("@text", "Merhaba, dünya!");
insert.ExecuteNonQuery();
Console.WriteLine("Not eklendi!");
4. Gerçek Dünya Kullanım Senaryoları
4.1 Data Science & Hızlı Veri Analizi
- Excel veya CSV verisi okuyup istatistik çıkarmak için tek dosya script
- Örneğin: CSV dosyalarının fiziksel satır sayısını bulmak. Aşağıdaki örnek sütunları veya CSV kayıtlarını ayrıştırmaz; tırnak içindeki çok satırlı alanlar nedeniyle satır sayısı kayıt sayısından farklı olabilir.
using System.IO;
var files = Directory.GetFiles(
Directory.GetCurrentDirectory(),
"*.csv"
);
foreach (var file in files)
{
var count = File.ReadLines(file).LongCount();
Console.WriteLine(
$"{Path.GetFileName(file)}: {count} fiziksel satır"
);
}
4.2 Otomasyon ve Batch İşlemler
- Klasördeki resimleri yeniden adlandırmak veya boyutlandırmak için küçük script’ler
- Sunucuya otomatik yedekleme için gece çalışan mini kodlar
4.3 Eğitim, Demo ve Topluluk Paylaşımı
- StackOverflow, blog, Github gibi ortamlarda paylaşılacak örnek kodlar
- Kaynak kodu tek dosya olarak paylaşabilirsiniz; çalıştıracak kişinin uyumlu .NET SDK’ya, paket kaynaklarına ve gerekiyorsa native bağımlılıklara erişimi olmalıdır.
5. Projesiz ve Klasik C# Proje Akışının Karşılaştırılması
| Özellik | Projesiz C# (.NET 10+) | Klasik Proje (.csproj) |
|---|---|---|
| Başlangıç | Tek dosya ile | Proje gerekir; solution isteğe bağlı |
| Paket yönetimi | #:package ile baştan eklenir | NuGet & .csproj ile |
| SDK ayarı | #:sdk ile | .csproj’a eklenir |
| Derleme/Çalıştırma | dotnet run dosya.cs |
dotnet run |
| Hedef | Script, CLI, hızlı deneme | Büyük uygulama, prod kod |
| Sürüm Yönetimi | Paket sürümleri dosyada; .NET SDK seçimi global.json ile | Paketler .csproj/merkezi yönetimde; .NET SDK seçimi global.json ile |
| Dosya Sayısı | Tek giriş dosyası; #:include desteği SDK sürümüne bağlı | Çoklu dosya |
| IDE Desteği | Editör ve C# araçlarının sürümüne bağlı | Gelişmiş (Visual Studio) |
6. Projesiz C# hangi işleri kolaylaştırır?
- Zamandan Tasarruf: Proje oluştur, ayar yap, NuGet config ile uğraş derdi yok.
- Taşınabilirlik: Kaynak dosyayı paylaşmak kolaydır; ancak kullanılan paketlerin ve native bileşenlerin platform desteğini ayrıca kontrol edin.
- Karmaşıklıktan Kurtuluş: Küçük işler için proje şişkinliği yok.
- Bağımlılık yönetimi: #:package ile NuGet paketlerini dosyada tanımlayabilirsiniz. Restore, ağ ve NuGet yapılandırması gereksinimlerini ortadan kaldırmaz.
- Eğitimde Kolaylık: Öğrencilere, geliştiricilere “projesiz” hızlı deneme imkanı.
- Geliştirici Deneyimi: Hızlı prototip ve hata ayıklama için birebir.
7. Sınırlar ve bakım maliyeti
- Büyük Proje Yönetimi Zor: Script büyüdükçe takip ve bakım güçleşir.
- Dosya organizasyonu: .NET SDK 10.0.300 ve sonrasında #:include ile ek C# dosyalarını dahil edebilirsiniz. Bu dosyalar ek top-level statements içeremez; büyük çözümde proje sınırlarını açık tutmak yine önemlidir.
- IDE desteği: Editör ve C# araçlarının sürümüne bağlıdır. Güncel araçları kontrol edin; refactoring veya IntelliSense için her durumda .csproj zorunlu olduğu iddiası doğru değildir.
- CI/CD: dotnet build dosya.cs ve dotnet publish dosya.cs ile pipeline kurabilirsiniz. SDK, paket sürümleri, secret yönetimi ve test adımlarını açıkça tanımlayın.
- Yayınlama/dağıtım: File-based app publish destekler. Native AOT varsayılan olabilir; dynamic/reflection kullanan paketlerde uyumluluğu doğrulayın veya #:property PublishAot=false ile JIT dağıtımı seçin.
8. Sık Yapılan Hatalar & İpuçları
#:packagesatırında paket adı/sürümünü yanlış yazmak → derleme hatası alırsın.- Çoklu paket eklerken, sürüm çakışmasına dikkat et.
- Script dosyasını gereğinden fazla büyütüp, bir “spaghetti code”a dönüştürmekten kaçın.
- Üretim için seçimde kaynak dosyası sayısından önce test, gözlemlenebilirlik, bağımlılık ve deployment gereksinimlerini değerlendirin. Kritik ve büyüyen uygulamalarda klasik proje yapısı bakım açısından daha uygun olabilir.
- Script dosyanı, platform bağımsız çalışacak şekilde (örn. yol ayrımları) yazmaya dikkat et.
9. İleri Seviye Kod Örnekleri
9.1 Dış Servis ile Entegrasyon (Mail Gönderme)
#:package MailKit@4.17.0
using MailKit.Net.Smtp;
using MailKit.Security;
using MimeKit;
string Required(string name) => Environment.GetEnvironmentVariable(name)
?? throw new InvalidOperationException($"{name} ortam değişkeni gerekli.");
var mesaj = new MimeMessage();
mesaj.From.Add(MailboxAddress.Parse(Required("SMTP_FROM")));
mesaj.To.Add(MailboxAddress.Parse(Required("SMTP_TO")));
mesaj.Subject = "Test Mail";
mesaj.Body = new TextPart("plain") { Text = "Selamlar!" };
using var smtp = new SmtpClient { Timeout = 15000 };
await smtp.ConnectAsync(Required("SMTP_HOST"), 587, SecureSocketOptions.StartTls);
await smtp.AuthenticateAsync(Required("SMTP_USER"), Required("SMTP_PASSWORD"));
await smtp.SendAsync(mesaj);
await smtp.DisconnectAsync(true);
Console.WriteLine("E-posta gönderildi!");
9.2 Web Scraping (HTML’den Veri Çekme)
#:package HtmlAgilityPack@1.12.4
using HtmlAgilityPack;
using var client = new HttpClient { Timeout = TimeSpan.FromSeconds(15) };
var source = await client.GetStringAsync("https://news.ycombinator.com/");
var doc = new HtmlDocument();
doc.LoadHtml(source);
var basliklar = doc.DocumentNode.SelectNodes("//span[contains(concat(' ', normalize-space(@class), ' '), ' titleline ')]/a[1]");
if (basliklar is null)
{
Console.Error.WriteLine("Başlık bulunamadı; sayfa yapısını kontrol edin.");
return 1;
}
foreach (var b in basliklar)
Console.WriteLine(HtmlEntity.DeEntitize(b.InnerText));
return 0;
9.3 CSV’den JSON’a Dönüştürme
#:package CsvHelper@33.1.0
#:package Newtonsoft.Json@13.0.4
#:property PublishAot=false
using System.IO;
using CsvHelper;
using Newtonsoft.Json;
using System.Globalization;
using var reader = new StreamReader("veri.csv");
using var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
var kayitlar = csv.GetRecords<dynamic>().ToList();
var json = JsonConvert.SerializeObject(kayitlar, Formatting.Indented);
File.WriteAllText("veri.json", json);
Console.WriteLine("Dönüşüm tamamlandı!");
10. Sıkça sorulan sorular
.csproj tamamen bitiyor mu?
Hayır. Projesiz C# küçük araçların başlangıcını sadeleştirir. Büyüyen uygulamalarda proje ve solution yapısı, test ve dependency sınırlarını yönetmeyi kolaylaştırır.
Her platformda çalışır mı?
Uyumlu .NET 10 SDK gerekir; yalnız runtime yeterli değildir. Paket, native bağımlılık ve API’lerin platform desteğini ayrıca kontrol edin.
Birden fazla C# dosyası kullanabilir miyim?
.NET SDK 10.0.300 ve sonrasında #:include desteği vardır. Dahil edilen dosyalar tip ve metot tanımlayabilir, ek top-level statements içeremez. Daha eski SDK’da bu desteği varsaymayın.
Paket çakışması olursa ne olur?
Restore veya build çıktısını inceleyin; paket sürümlerini ve transitive dependency uyumunu kontrol edin.
Yayımlayabilir miyim?
Evet, dotnet publish dosya.cs desteklenir. Native AOT için platform toolchain’i ve paket uyumluluğunu doğrulayın. Örneklerdeki dynamic/reflection kullanımları için PublishAot=false belirtilmiştir.
JSON ve CSV örnekleri küçük veri içindir; tüm sonuçları belleğe alma maliyetini büyük dosyalarda ayrıca değerlendirin. SQLite örneğini yeniden çalıştırmak yeni bir not ekler. Mail örneği gerçek SMTP bilgileri ve gönderim yetkisi gerektirir; credential’ları kaynak koduna yazmayın. Scraping selector’ı hedef sitenin HTML’i değiştiğinde yeniden kontrol edin.
Temel komut ve direktifler için Microsoft’un file-based apps referansını inceleyin. Uygulama büyüdüğünde test sınırlarını kurmak için Dependency Injection rehberi de yardımcı olabilir.
11. Kaynaklar
- Microsoft .NET Blog – File-based apps duyurusu
- Hobimiz Teknoloji: C# Proje Dosyalarına Elveda mı?
- Microsoft’s Linux-friendly approach to C# scripting is planned for .NET 10
- Running C# without csproj files
