File-scoped features to nowoczesne podejście do organizacji kodu! W 2015 roku każdy plik miał namespace z klamrami i długą listę using statements. W 2026 roku masz file-scoped namespaces, global usings, implicit usings, i file-local types - mniej boilerplate, czystszy kod!
📅 Timeline - ewolucja file-scoped features
C# 1.0-9.0 (do 2020) - Namespaces z klamrami, using w każdym pliku
C# 10 (2021) - 🔥 File-scoped namespaces + Global usings!
.NET 6+ (2021) - Implicit usings - automatyczne!
C# 11 (2022) - 🔥 File-local types!
Problem - boilerplate wszędzie
// Przed C# 10 - namespace z klamrami
using System;
using System.Collections.Generic;
using System.Linq;
namespace MyCompany.MyProduct.Services // ← Klamra
{
public class UserService // ← Dodatkowa indentacja
{
public User GetUser(int id) // ← Jeszcze więcej indentacji
{
return new User();
}
}
} // ← Zamykająca klamra
// Problemy:
// - Dodatkowy poziom indentacji
// - Te same usingi w KAŻDYM pliku
// - Bezużyteczna zamykająca klamra
🔥 File-scoped Namespaces (C# 10)
🎉 C# 10 - File-scoped Namespace
namespace MyApp; bez klamer - jeden poziom mniej indentacji! ✨
// C# 10+ - file-scoped namespace
using System;
namespace MyCompany.MyProduct.Services; // ← Średnik!
public class UserService // ← Bez dodatkowej indentacji!
{
public User GetUser(int id)
{
return new User();
}
}
// Zalety:
// ✅ Jeden poziom mniej indentacji
// ✅ Brak zbędnej klamry
// ✅ Czystszy kod
❌ Przed C# 10
namespace MyApp
{
public class User
{
public void Method()
{
// 3 poziomy!
}
}
}
✅ C# 10+
namespace MyApp;
public class User
{
public void Method()
{
// 2 poziomy! ✨
}
}
🔥 Global Usings (C# 10)
🎉 C# 10 - Global Usings
global using System; - raz dla CAŁEGO projektu!
// File: GlobalUsings.cs
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
// Te usingi są dostępne w KAŻDYM pliku!
// File: UserService.cs
namespace MyApp.Services; // ← Brak using statements!
public class UserService
{
public List<User> GetUsers() // List z global using!
{
return _users.Where(u => u.IsActive).ToList(); // Linq z global using!
}
}
Organizacja global usings
// GlobalUsings.cs
global using System;
global using System.Collections.Generic;
global using System.Linq;
global using System.Threading.Tasks;
global using MyApp.Core.Entities; // Twoje namespaces
global using Microsoft.Extensions.Logging; // Third-party
// Teraz NIE musisz dodawać tych usings w żadnym pliku! ✨
Implicit Usings (.NET 6+)
🎉 .NET 6+ - Implicit Usings
SDK automatycznie dodaje global usings! Włączone domyślnie!
// .csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings> <!-- Domyślnie włączone -->
</PropertyGroup>
</Project>
// SDK automatycznie dodaje:
// - System
// - System.Collections.Generic
// - System.IO
// - System.Linq
// - System.Threading
// - System.Threading.Tasks
// + więcej dla ASP.NET Core
// Efekt: Większość plików NIE POTRZEBUJE żadnych usings! ✨
Minimal API bez usings
// Program.cs - ZERO using statements!
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.MapGet("/users", async () =>
{
await Task.Delay(100);
return new List<User> { new User { Name = "Jan" } };
});
app.Run();
// Wszystko z implicit usings! ✨
🔥 File-local Types (C# 11)
🎉 C# 11 - File-local Types
file class - typ widoczny TYLKO w tym pliku!
// File: UserService.cs
namespace MyApp.Services;
// file class - widoczne TYLKO w tym pliku!
file class UserValidator
{
public bool Validate(User user) => !string.IsNullOrEmpty(user.Name);
}
file record UserDto(string Name, int Age);
public class UserService
{
public void CreateUser(User user)
{
var validator = new UserValidator(); // ✅ OK
var dto = new UserDto(user.Name, user.Age); // ✅ OK
}
}
// File: OrderService.cs
namespace MyApp.Services;
public class OrderService
{
// UserValidator NIE jest widoczny tutaj!
// var v = new UserValidator(); // ❌ BŁĄD!
}
Use cases
// Helper classes używane tylko w jednym pliku
file class ReportFormatter { }
file class ReportValidator { }
// DTOs używane tylko w jednym serwisie
file record CreateUserRequest(string Name);
file record UserResponse(int Id, string Name);
// Enums używane tylko w jednej klasie
file enum ProcessingStage { Validation, Payment, Completed }
Modifier
Zasięg
file class
Tylko ten plik
private class (nested)
Tylko outer class
internal class
Cały assembly
public class
Wszędzie
Organizacja kodu w 2026
Nowoczesny plik w 2026
// UserService.cs
namespace MyApp.Services; // File-scoped
file class UserValidator { } // File-local helper
public class UserService
{
private readonly ILogger<UserService> _logger; // Z global using
public async Task<User> CreateUserAsync(User user) // Task z implicit
{
var validator = new UserValidator();
await _repository.SaveAsync(user);
return user;
}
}
// Porównaj z 2015:
// - Brak 5 linii using statements
// - Brak namespace { }
// - Jeden poziom mniej indentacji
// - Czystszy kod! ✨
Struktura projektu
// Struktura w 2026:
📁 MyApp
📄 GlobalUsings.cs ← Global usings
📁 Services
📄 UserService.cs ← File-scoped + file-local
📄 OrderService.cs
📁 Controllers
📄 UsersController.cs
// GlobalUsings.cs:
global using System;
global using System.Linq;
global using MyApp.Entities;
// Każdy plik:
namespace MyApp.Services;
file class Helper { }
public class Service { }
💡 Refactoring 2015 → 2026
// ❌ 2015 (30 linii)
using System;
using System.Linq;
using System.Threading.Tasks;
namespace MyApp.Services
{
public class UserService
{
public async Task<User> Get()
{
await Task.Delay(100);
return new User();
}
}
}
// ✅ 2026 (15 linii - POŁOWA!)
namespace MyApp.Services;
public class UserService
{
public async Task<User> Get()
{
await Task.Delay(100);
return new User();
}
}
Best practices
// ✅ DO:
namespace MyApp.Services; // File-scoped
global using System; // GlobalUsings.cs
file class Helper { } // File-local
// ❌ DON'T:
namespace MyApp.Services { } // Stare
using System; // W każdym pliku
internal class Helper { } // Użyj file
Podsumowanie
✅ 🔥 File-scoped namespaces - namespace MyApp; bez klamer
✅ 🔥 Global usings - global using dla całego projektu