Free .NET Web API Course

dotnet run app.cs - Run C# Without a Project File in .NET 10

Run C# like Python with dotnet run app.cs in .NET 10. Complete guide with directives, practical examples, Native AOT publishing, and CLI reference.

dotnet webapi-course

dotnet 10 file-based apps dotnet-webapi-zero-to-hero-course scripting

15 min read
1.9K views

What if I told you that you can now write C# like Python? Just create a .cs file, write your code, and run it directly. No .csproj file. No solution. No ceremony.

That’s exactly what .NET 10 brings with file-based apps — a game-changer for scripting, prototyping, and learning C#.

In this article, we’ll explore how file-based apps work, all the directives you can use, practical examples for scripting and data processing, and when you should (or shouldn’t) use this feature.

The sample code for this article is available in the .NET Web API Zero to Hero course repository under modules/01-getting-started/file-based-apps/.

Let’s get into it.

What Are File-Based Apps?

File-based apps are a new feature in .NET 10 that lets you write and run C# programs from a single .cs file without creating a project file. Think of it like running a Python script — just write code and execute it.

Before .NET 10, even the simplest C# program required:

  • A .csproj project file
  • Often a solution file (.sln)
  • The dotnet new command to scaffold everything

Now? You just need this:

Console.WriteLine("Hello from file-based apps!");

Save it as hello.cs and run:

Terminal window
dotnet hello.cs

That’s it. No boilerplate. No ceremony. Just code.

This is built on top of top-level statements (introduced in C# 9) but takes it further by eliminating the need for project infrastructure entirely.

Why Does This Matter?

File-based apps solve real problems that .NET developers have faced for years:

  1. Learning C# is now easier — Beginners don’t need to understand MSBuild, project files, or solution structures just to print “Hello World”
  2. Quick prototyping — Test an idea in seconds without creating a full project
  3. Scripting in C# — Replace Bash or PowerShell scripts with type-safe C# code
  4. One-off utilities — Write a quick data converter or file processor without project overhead
  5. Better samples — Library authors can include runnable examples without cluttering repos with project files

The barrier to entry just dropped from “learn project files and MSBuild” to “write C# and run it.”

Getting Started

Prerequisites

You need the .NET 10 SDK installed. Download it from dotnet.microsoft.com/download/dotnet/10.0.

Verify your installation:

Terminal window
dotnet --version
# Should show 10.0.x

Your First File-Based App

Create a file named hello.cs:

Console.WriteLine("Hello from .NET 10!");
Console.WriteLine($"Running on {Environment.OSVersion}");
Console.WriteLine($"Current time: {DateTime.Now:F}");

Run it:

Terminal window
dotnet hello.cs

Output:

Hello from .NET 10!
Running on Microsoft Windows NT 10.0.22631.0
Current time: Sunday, January 26, 2026 10:30:00 AM

The first run takes a moment because the SDK compiles the code. Subsequent runs are faster thanks to caching.

All Available Directives

File-based apps use special directives (prefixed with #:) to configure packages, SDKs, and build properties. These must be placed at the top of your file.

#:package — Add NuGet Packages

Add NuGet package references directly in your code:

#:package Newtonsoft.Json@13.0.3
#:package Serilog@4.0.0
#:package Spectre.Console@*

Version syntax options:

  • Exact version: #:package [email protected]
  • Wildcard (latest): #:package Spectre.Console@*
  • Partial wildcard: #:package CsvHelper@33.*

#:sdk — Specify the SDK

By default, file-based apps use Microsoft.NET.Sdk. For web applications, you need the Web SDK:

#:sdk Microsoft.NET.Sdk.Web

For .NET Aspire:

#:sdk Aspire.AppHost.Sdk@9.0.0

#:property — Set MSBuild Properties

Configure any MSBuild property you’d normally put in a .csproj:

#:property LangVersion=preview
#:property Nullable=disable
#:property PublishAot=false
#:property TargetFramework=net10.0

#:project — Reference Other Projects

Reference existing project files:

#:project ../SharedLibrary/SharedLibrary.csproj

Shebang Support (Unix/Linux/macOS)

Make your file directly executable on Unix-like systems:

#!/usr/bin/env dotnet
Console.WriteLine("I'm a script!");

Then:

Terminal window
chmod +x script.cs
./script.cs

Note: Shebang requires LF line endings (not CRLF) and no BOM. This doesn’t work on Windows.

CLI Commands Reference

Here’s everything you can do with file-based apps:

CommandDescription
dotnet run hello.csBuild and run
dotnet hello.csShorthand for run
dotnet build hello.csBuild only (output in temp folder)
dotnet publish hello.csPublish (Native AOT by default!)
dotnet pack hello.csPackage as .NET tool
dotnet project convert hello.csConvert to full project
dotnet clean hello.csClean build artifacts
dotnet restore hello.csRestore packages
dotnet run hello.cs -- arg1 arg2Pass arguments to your program

Passing Arguments

Use -- to separate CLI arguments from your program’s arguments:

args.cs
foreach (var arg in args)
{
Console.WriteLine($"Argument: {arg}");
}
Terminal window
dotnet args.cs -- hello world --verbose

Output:

Argument: hello
Argument: world
Argument: --verbose

Piping from Stdin

You can even pipe code directly:

Terminal window
'Console.WriteLine("Hello from stdin!");' | dotnet run -

Practical Examples

Let’s look at real-world scenarios where file-based apps shine.

Example 1: System Info Script

Let’s start with something simple — a script that displays information about your system. This is useful for debugging environment issues or just quickly checking your setup. No external packages needed.

Create sysinfo.cs:

Console.WriteLine("=== System Information ===");
Console.WriteLine();
Console.WriteLine($"Machine Name: {Environment.MachineName}");
Console.WriteLine($"User Name: {Environment.UserName}");
Console.WriteLine($"OS: {Environment.OSVersion}");
Console.WriteLine($".NET Version: {Environment.Version}");
Console.WriteLine($"64-bit OS: {Environment.Is64BitOperatingSystem}");
Console.WriteLine($"64-bit Process: {Environment.Is64BitProcess}");
Console.WriteLine($"Processor Count: {Environment.ProcessorCount}");
Console.WriteLine($"Current Dir: {Environment.CurrentDirectory}");
Console.WriteLine();
Console.WriteLine("=== Environment Variables ===");
Console.WriteLine();
Console.WriteLine($"PATH entries: {Environment.GetEnvironmentVariable("PATH")?.Split(Path.PathSeparator).Length ?? 0}");
Console.WriteLine($"TEMP: {Path.GetTempPath()}");

Run it:

Terminal window
dotnet sysinfo.cs

Output:

=== System Information ===
Machine Name: DEV-WORKSTATION
User Name: mukesh
OS: Microsoft Windows NT 10.0.22631.0
.NET Version: 10.0.0
64-bit OS: True
64-bit Process: True
Processor Count: 16
Current Dir: C:\scripts
=== Environment Variables ===
PATH entries: 42
TEMP: C:\Users\mukesh\AppData\Local\Temp\

This is about as simple as it gets — pure C# with no packages, no directives, just code. The Environment class gives you access to all sorts of system information. You could extend this to check for specific tools, SDK versions, or environment variables your project needs.

Example 2: Password Generator

Here’s a practical utility you’ll actually use — a random password generator. It creates secure passwords with a mix of characters, and you can specify the length via command-line arguments.

Create passgen.cs:

using System.Security.Cryptography;
const string lowercase = "abcdefghijklmnopqrstuvwxyz";
const string uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string digits = "0123456789";
const string special = "!@#$%^&*()_+-=[]{}|;:,.<>?";
var allChars = lowercase + uppercase + digits + special;
var length = args.Length > 0 && int.TryParse(args[0], out var len) ? len : 16;
if (length < 8 || length > 128)
{
Console.WriteLine("Password length must be between 8 and 128 characters.");
return;
}
var password = new char[length];
for (int i = 0; i < length; i++)
{
password[i] = allChars[RandomNumberGenerator.GetInt32(allChars.Length)];
}
Console.WriteLine($"Generated password ({length} chars):");
Console.WriteLine(new string(password));

Run it:

Terminal window
dotnet passgen.cs
dotnet passgen.cs -- 24
dotnet passgen.cs -- 32

Output:

Generated password (16 chars):
kP9#mX2$vL5@nQ8!
Generated password (24 chars):
Hj3$kL9@mN5#pQ2!xR7&vB4^
Generated password (32 chars):
aK8#mP3$xL5@nQ9!hR2&vB7^jT4%wC6*

Code Walkthrough

Character sets — We define four character categories: lowercase, uppercase, digits, and special characters. Combining them gives us a pool of 85 characters.

Argument parsing — The script checks args[0] for a custom length. If not provided or invalid, it defaults to 16 characters. We also validate the length is between 8 and 128.

Secure randomness — Instead of Random, we use RandomNumberGenerator.GetInt32() from System.Security.Cryptography. This provides cryptographically secure random numbers, which is important for password generation.

Building the password — We create a character array and fill each position with a random character from our pool, then convert it to a string for output.

This is the kind of utility that’s perfect for file-based apps — something you need occasionally, want to run quickly, and don’t want to maintain as a full project.

Example 3: Data Processing

One of the most common scripting tasks is transforming data from one format to another. Let’s say you have a sales.json file with transaction records, and you need to generate a CSV summary grouped by product. Normally, you’d create a console project, add NuGet packages, write the code, and then run it. With file-based apps, you can do this in a single file.

Here’s what we’re building: a script that reads sales data from JSON, groups it by product, calculates totals, and outputs a CSV file.

First, create a sample sales.json file to work with:

[
{ "Product": "Laptop", "Amount": 999.99, "Date": "2026-01-15" },
{ "Product": "Mouse", "Amount": 29.99, "Date": "2026-01-15" },
{ "Product": "Laptop", "Amount": 999.99, "Date": "2026-01-16" },
{ "Product": "Keyboard", "Amount": 79.99, "Date": "2026-01-16" },
{ "Product": "Mouse", "Amount": 29.99, "Date": "2026-01-17" }
]

Now create data-processor.cs:

#:package CsvHelper@33.0.0
using System.Text.Json;
using System.Text.Json.Serialization;
using CsvHelper;
using System.Globalization;
// Read JSON using source-generated serializer (AOT-compatible)
var json = await File.ReadAllTextAsync("sales.json");
var sales = JsonSerializer.Deserialize(json, SaleJsonContext.Default.ListSale)!;
// Process and write CSV
var summary = sales
.GroupBy(s => s.Product)
.Select(g => new SaleSummary(g.Key, g.Sum(s => s.Amount), g.Count()))
.OrderByDescending(x => x.TotalRevenue);
using var writer = new StreamWriter("summary.csv");
using var csv = new CsvWriter(writer, CultureInfo.InvariantCulture);
csv.WriteRecords(summary);
Console.WriteLine("Done! Check summary.csv");
record Sale(string Product, decimal Amount, DateTime Date);
record SaleSummary(string Product, decimal TotalRevenue, int Count);
[JsonSerializable(typeof(List<Sale>))]
partial class SaleJsonContext : JsonSerializerContext { }

Note: Since file-based apps use Native AOT by default, we use source-generated JSON serialization instead of reflection-based. The [JsonSerializable] attribute generates the serialization code at compile time, making it AOT-compatible.

Run it:

Terminal window
dotnet data-processor.cs

Code Walkthrough

Package directive — We only need CsvHelper as an external package. System.Text.Json is already included in the .NET runtime.

Source-generated JSON — Since file-based apps use Native AOT by default, reflection-based serialization is disabled. The SaleJsonContext class with the [JsonSerializable] attribute tells the compiler to generate serialization code at compile time. This is the AOT-compatible way to use System.Text.Json.

Reading and deserializing — We read the JSON file and deserialize using SaleJsonContext.Default.ListSale instead of the generic Deserialize<T>() method. This uses the source-generated serializer.

LINQ aggregation — The code groups sales by product, then projects each group into a SaleSummary record with the product name, total revenue, and count. We use a concrete record type instead of an anonymous type for better AOT compatibility.

Writing CSV — CsvHelper handles the CSV formatting. We create a StreamWriter for the output file and pass it to CsvWriter, which writes the records with proper headers.

The output summary.csv will look like:

Product,TotalRevenue,Count
Laptop,1999.98,2
Keyboard,79.99,1
Mouse,59.98,2

This entire workflow — reading JSON, transforming data, writing CSV — happens in one file with zero project setup. Quite handy for ad-hoc data tasks, yeah?

Example 4: CLI Tool with Argument Parsing

Sometimes you need a reusable command-line utility with proper argument handling. Instead of manually parsing args[], you can use Microsoft’s System.CommandLine library to get features like help text, validation, and tab completion — all in a single file.

Here’s what we’re building: a file statistics tool that counts lines, words, and characters in any text file. It supports a --file argument to specify the input and a --verbose flag for detailed output.

Create file-stats.cs:

#:package System.CommandLine@2.0.0
using System.CommandLine;
var fileOption = new Option<FileInfo?>("--file") { Description = "The file to process" };
var verboseOption = new Option<bool>("--verbose") { Description = "Show detailed output" };
var rootCommand = new RootCommand("File statistics utility - counts lines, words, and characters")
{
fileOption,
verboseOption
};
rootCommand.SetAction(async (parseResult, cancellationToken) =>
{
var file = parseResult.GetValue(fileOption);
var verbose = parseResult.GetValue(verboseOption);
if (file is null)
{
Console.WriteLine("No file specified. Use --file <path>");
return 1;
}
if (!file.Exists)
{
Console.WriteLine($"File not found: {file.FullName}");
return 1;
}
if (verbose)
Console.WriteLine($"Processing: {file.FullName}");
var lines = await File.ReadAllLinesAsync(file.FullName, cancellationToken);
Console.WriteLine($"Lines: {lines.Length}");
Console.WriteLine($"Words: {lines.Sum(l => l.Split(' ', StringSplitOptions.RemoveEmptyEntries).Length)}");
Console.WriteLine($"Characters: {lines.Sum(l => l.Length)}");
return 0;
});
return await rootCommand.Parse(args).InvokeAsync();

Run it:

Terminal window
dotnet file-stats.cs -- --file myfile.txt --verbose

You can also get auto-generated help:

Terminal window
dotnet file-stats.cs -- --help

Output:

Description:
File statistics utility - counts lines, words, and characters
Usage:
file-stats [options]
Options:
--file <file> The file to process
--verbose Show detailed output
--version Show version information
-?, -h, --help Show help and usage information

Code Walkthrough

Defining options — We create two Option<T> objects: one for the file path (which System.CommandLine automatically converts to a FileInfo) and one for the verbose flag. Each option has a name and description.

Building the command — The RootCommand is the entry point for our CLI. We add both options to it using collection initializer syntax.

Setting the action — In System.CommandLine 2.0, we use SetAction with an async delegate. The delegate receives a ParseResult and CancellationToken as parameters.

Getting parsed values — Inside the action, we use parseResult.GetValue() to retrieve the parsed option values. This is type-safe and returns the correct type for each option.

Validation — We check if a file was provided and if it exists. Returning 1 indicates an error, while 0 means success.

Processing — We read all lines asynchronously and use LINQ to calculate statistics. The StringSplitOptions.RemoveEmptyEntries ensures we don’t count empty strings as words.

Invoking the command — We call rootCommand.Parse(args).InvokeAsync() to parse the arguments and execute the action. The exit code is returned to the shell.

The -- separator in the run command tells the .NET CLI that everything after it should be passed to your program, not interpreted as dotnet options.

This is how file-based apps let you build proper CLI tools without any project ceremony. You get all the benefits of System.CommandLine — help text, validation, error handling — in a single script file.

Native AOT — Enabled by Default!

Here’s something important: file-based apps publish with Native AOT enabled by default.

When you run dotnet publish hello.cs, you get:

  • A self-contained executable
  • No .NET runtime dependency
  • Faster startup time
  • Smaller memory footprint

This is perfect for CLI tools and utilities.

If you need to disable Native AOT (for example, if you’re using reflection-heavy libraries):

#:property PublishAot=false
// Your code here

Configuration and Secrets

Using appsettings.json

With the Web SDK, configuration files are automatically included:

#:sdk Microsoft.NET.Sdk.Web
var builder = WebApplication.CreateBuilder(args);
// appsettings.json is automatically loaded
var connectionString = builder.Configuration.GetConnectionString("Default");
Console.WriteLine($"Connection: {connectionString}");

Create appsettings.json in the same directory:

{
"ConnectionStrings": {
"Default": "Server=localhost;Database=MyDb"
}
}

User Secrets

Yes, user secrets work with file-based apps!

Terminal window
dotnet user-secrets set "ApiKey" "my-secret-key" --file api.cs
dotnet user-secrets list --file api.cs

The secrets ID is generated based on your file path hash.

Launch Profiles

Create a [filename].run.json file alongside your .cs file for launch configuration:

{
"profiles": {
"development": {
"commandName": "Project",
"launchBrowser": true,
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"production": {
"commandName": "Project",
"applicationUrl": "http://localhost:5001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
}
}
}
}

Run with a specific profile:

Terminal window
dotnet run api.cs --launch-profile production

Converting to a Full Project

When your file-based app grows too complex, convert it to a standard project:

Terminal window
dotnet project convert api.cs

This command:

  1. Creates a new directory named after your file
  2. Generates a proper .csproj file
  3. Moves your code (removing #: directives)
  4. Translates directives into MSBuild properties and package references

Before (api.cs):

#:sdk Microsoft.NET.Sdk.Web
#:package Microsoft.AspNetCore.OpenApi@10.0.0
var builder = WebApplication.CreateBuilder(args);
// ...

After (api/api.csproj):

<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<PublishAot>true</PublishAot>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.0" />
</ItemGroup>
</Project>

And api/api.cs (directives removed):

var builder = WebApplication.CreateBuilder(args);
// ...

You can also specify a custom output directory:

Terminal window
dotnet project convert api.cs --output MyApiProject

How It Works Under the Hood

When you run dotnet hello.cs, here’s what happens:

  1. Validation — The SDK confirms the file ends with .cs or starts with #!
  2. Directive Parsing — Roslyn extracts all #: directives from the file
  3. Virtual Project Generation — An in-memory .csproj is created with your directives translated to MSBuild elements
  4. Build Execution — MSBuild runs Restore and Build targets
  5. Caching — Artifacts are stored in a temp folder for faster subsequent runs
  6. Execution — The compiled app runs

Cache location: <temp>/dotnet/runfile/<appname>-<filehash>/

To clean the cache:

Terminal window
dotnet clean hello.cs
dotnet clean file-based-apps # Clean all cached file-based apps
dotnet clean file-based-apps --days 7 # Remove unused for 7+ days

Folder Layout Best Practices

Here’s an important gotcha that can cause unexpected behavior: don’t nest file-based apps inside project directories.

The Anti-Pattern

❌ BAD - Don't do this:
MyProject/
├── MyProject.csproj
├── Program.cs
└── scripts/
└── utility.cs ← This will cause problems!

When you run dotnet utility.cs from inside a project folder, the SDK gets confused. It may try to build the parent project instead, or you’ll get unexpected build conflicts.

The Correct Approach

✅ GOOD - Keep file-based apps separate:
MyProject/
├── MyProject.csproj
└── Program.cs
scripts/
├── utility.cs
├── data-processor.cs
└── sysinfo.cs

By keeping your file-based apps in a separate directory (sibling to your projects, not nested inside them), you avoid build conflicts and make it clear which files are standalone scripts vs. project source files.

Tip: Create a scripts/ folder at the root of your repository for all your file-based utilities. This keeps them organized and prevents accidental inclusion in project builds.

Implicit Build Files

File-based apps automatically respect configuration files from the same or parent directories:

  • global.json — SDK version pinning
  • NuGet.config — Package sources
  • Directory.Build.props / Directory.Build.targets — Shared MSBuild properties
  • Directory.Packages.props — Central package management

This means you can create a Directory.Build.props to share settings across multiple file-based apps:

<!-- Directory.Build.props -->
<Project>
<PropertyGroup>
<LangVersion>preview</LangVersion>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>

What’s NOT Supported

Before diving into limitations, let’s be explicit about what’s not coming to file-based apps:

  • Visual Basic .NET — No plans to support VB.NET file-based apps
  • F# — No plans for F# support (though the community has requested it)
  • Visual Studio support — Currently works with VS Code and CLI only; full VS support is not planned for the initial release
  • Multi-file apps — Planned for .NET 11, not .NET 10

The .NET team has been clear that file-based apps are designed for C# scripting scenarios, not as a replacement for traditional project-based development.

Current Limitations

Before you go all-in on file-based apps, be aware of these limitations:

LimitationDetails
Single file onlyMulti-file support is planned for .NET 11
No Visual Studio supportWorks with VS Code and CLI only
No VB.NET or F# supportC# only for now
No direct assembly referencesUse Directory.Build.targets as a workaround
IntelliSense has issuesKnown issue in VS Code (GitHub #49293)
Not for productionBest for scripting, prototyping, and learning

When to Use File-Based Apps

Perfect for:

  • Learning C# and .NET
  • Quick prototyping and experiments
  • One-off scripts and utilities
  • CI/CD automation scripts
  • Sample code in library repos
  • Data processing and transformations

Not recommended for:

  • Production applications
  • Large or complex projects
  • Team projects requiring full IDE support
  • Applications needing multiple source files

File-Based Apps vs. CSX Scripts

If you’ve used .csx scripts before, here’s how file-based apps compare:

FeatureFile-based Apps (.cs)CSX Scripts (.csx)
Built into SDKYesNo (third-party)
Standard C# syntaxYesDifferent dialect
Convert to projectYesNo
REPL supportNoYes
Active developmentYesLimited
NuGet packages#:package#r "nuget:"

File-based apps use standard C# syntax, making it easy to copy code to/from regular projects.

Frequently Asked Questions

Can I use file-based apps in production?

File-based apps are not recommended for production applications. They're designed for scripting, prototyping, learning, and one-off utilities. For production workloads, convert to a full project using 'dotnet project convert' to get proper build pipelines, testing support, and IDE integration.

What's the difference between file-based apps and CSX scripts?

File-based apps use standard C# syntax and are built into the .NET 10 SDK — no third-party tools needed. CSX scripts use a different dialect and require external tools like dotnet-script. File-based apps can be converted to full projects, while CSX cannot. Both support NuGet packages, but with different directive syntax.

How do I add NuGet packages to a file-based app?

Use the #:package directive at the top of your file. For example: '#:package [email protected]' for a specific version, or '#:package Spectre.Console@*' for the latest version. The SDK handles package restoration automatically on first run.

Does Visual Studio support file-based apps?

Not yet. File-based apps currently work with Visual Studio Code and the command line only. Full Visual Studio support is not planned for the initial .NET 10 release. Use VS Code with the C# Dev Kit extension for the best experience.

What happens when I run 'dotnet app.cs'?

The SDK validates your file, parses all #: directives, generates a virtual .csproj in a temp folder, restores NuGet packages, compiles your code, and runs the executable. The first run is slower due to compilation, but subsequent runs use cached artifacts and launch almost instantly.

Can I use multiple .cs files in a file-based app?

Not in .NET 10 — file-based apps are strictly single-file. Multi-file support is planned for .NET 11. For now, if you need multiple files, use 'dotnet project convert' to create a full project structure.

Do file-based apps support debugging?

Yes, you can debug file-based apps in VS Code. The SDK generates a temporary project that debuggers can attach to. Set breakpoints in your .cs file and use the standard debugging workflow. However, the experience is smoother with full projects.

Summary

File-based apps in .NET 10 are a significant quality-of-life improvement for .NET developers. They lower the barrier to entry for newcomers, speed up prototyping for experienced developers, and make C# a viable scripting language.

Key takeaways:

  • Run C# with dotnet hello.cs — no project file needed
  • Use #:package, #:sdk, #:property, and #:project directives
  • Native AOT is enabled by default for publishing
  • Convert to a full project when complexity grows with dotnet project convert
  • Not for production — best for learning, scripting, and prototyping

This is just the beginning. Multi-file support is coming in .NET 11, and IDE support will continue to improve.


This article is part of our FREE .NET Web API Zero to Hero SeriesStart the course here

If you found this helpful, share it with your colleagues — and if there’s a topic you’d like to see covered next, drop a comment and let me know.

Happy Coding :)

What's your Feedback?
Do let me know your thoughts around this article.

.NET + AI: Build Smarter, Ship Faster

Join 8,000+ developers learning to leverage AI for faster .NET development, smarter architectures, and real-world productivity gains.

AI + .NET tips
Productivity hacks
100% free
No spam, unsubscribe anytime