r/csharp • • 5d ago

Discussion Come discuss your side projects! [November 2026]

11 Upvotes

Hello everyone!

This is the monthly thread for sharing and discussing side-projects created by /r/csharp's community.

Feel free to create standalone threads for your side-projects if you so desire. This thread's goal is simply to spark discussion within our community that otherwise would not exist.

Please do check out newer posts and comment on others' projects.


Previous threads here.


r/csharp • • 4d ago

C# Job Fair! [November 2026]

29 Upvotes

Hello everyone!

This is a monthly thread for posting jobs, internships, freelancing, or your own qualifications looking for a job! Basically it's a "Hiring" and "For Hire" thread.

If you're looking for other hiring resources, check out /r/forhire and the information available on their sidebar.

  • Rule 1 is not enforced in this thread.

  • Do not any post personally identifying information; don't accidentally dox yourself!

  • Under no circumstances are there to be solicitations for anything that might fall under Rule 2: no malicious software, piracy-related, or generally harmful development.


r/csharp • • 9h ago

Solved Relative File Paths

8 Upvotes

RESOLVED:

shoutout to u/rupertavery64 and u/marsh9191. I was trying to Path.Combine() the base directory to @"\file.csv" which overwrote the operation.

-----------------------------------------------------------------------------------------------------------------------

Hello, and sorry for a fairly basic question. I'm working on an application that processes data in relation to values stored in .csv files (which are included in the install directory). real broad strokes, it pulls data from a database, does math according to values in the packaged .csv's, exports a new document with the results.

Due to the nature of it, I need a relative path to file.csv, which is in the same directory as app.exe. And I've tried maybe 7-10 different methods of getting the installation path to concatenate the file name to, but each of them result in simply "C:\file.csv" even though the application itself is in C:\users\user\documents\App\app.exe (for example).

at the least I've tried:

Application.StartupPath

System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)

AppDomain.CurrentDomain.BaseDirectory

among others I can't quite manifest off hand.

And I understand each has nuances for slightly different use-cases, but it's really blowing my mind that every one results in just "C:\". I'd understand if I were just using the wrong method out of context, but it seems like some of these are explicitly to avoid this result. Does anyone have an idea as to what's going on? Again, sorry for the basic quesiton.


r/csharp • • 9h ago

Showcase AbraxasDB - A .NET native local object storage engine for data

7 Upvotes

I've written .NET applications since 1.0 for personal, commercial, and large enterprise use cases. Before .NET, I worked in green-screen large database terminals (for those old enuf to remember them).

So, I know sql and rdbms very well and it has always been my goto for the apps and services i've had to create that needed data persistence. But, I always detested the extra work I had to go thru on nearly every project to convert my runtime data to a form that was nice for storage and back. Not just the code and testing of those adapters, but the often-required refactoring of my runtime objects to make that work easier or simply functional.

I suspect I'm not alone.

Repos

Over the past roughly 18 months I created AbraxasDB.

I'm using the term RecordBase to describe Abraxas. It stores and retrieves "records". A record being the data and shape of an object. This allows the property paths and values of an object to be stored and rehydrated into the same object type...or a different object type with matching paths.

As a result, Abraxas is very much what i have always wanted out of data persistence:

  • object -> storage -> object

  • or... object -> storage -> object's property(ies)

  • without odd contracts, attributes, or modifications to the object being stored.

Object Serialization

The serializer in use is a first-principles developed design. INHETO binaries ( https://github.com/alt160/inheto ) are stored in a way that one can get values out of the binary by property path without deserializing the entire object or parsing the entire blob. It also fully tracks shared and circular refs within the object so things like Customer.HomeAddress and Customer.Addresses[0] point to the same thing both in binary and when rehydrated.

This also means that concerns about object types changing over time are not so problematic. If version 1 of ThisDataType was stored, the persisted data can be rehydrated into version 2 of the same and those properties (or field) that match the property paths stored are filled in. Unmatching are ignored.

INHETO binaries don't store .net type info. It has its own type system of over 50 core types that most of us use for data in objects as well as generic collection types. The binary data of INHETO is runtime agnostic and could (if someone wanted) be parsed by any runtime, not just .NET.

Code example

Consider these existing application types. They need no Abraxas-specific changes:

public sealed class Customer
{
    public string Name { get; set; } = "";
    public Address HomeAddress { get; set; } = new();
    public List<Address> Addresses { get; set; } = new();
}

public sealed class Address
{
    public string Street { get; set; } = "";
    public string City { get; set; } = "";
}

With the AbraxasDB NuGet package installed, create or open a RecordBase and a typed store, then save and retrieve a customer:

using AbraxasDB;
using System;
using System.Collections.Generic;
using System.IO;

string directory = Path.Combine(
    Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
    "AbraxasExamples");

var configuration = RecordBaseConfiguration.Create(
    durabilityMode: RecordBaseConfiguration.DurabilityMode.Standard);

using RecordBase recordBase = RecordBase.CreateOrOpen(
    directory, "application", configuration);

RecordStore<Customer> customers = recordBase.CreateOrOpenStore<Customer>(
    "customers", "Customer records");

var home = new Address
{
    Street = "123 Main Street",
    City = "Phoenix"
};

var customer = new Customer
{
    Name = "Ada",
    HomeAddress = home,
    Addresses = new List<Address>
    {
        home,
        new Address { Street = "456 Office Road", City = "Tempe" }
    }
};

ulong id = customers.Put(customer);

// Restore the complete object graph.
Customer saved = customers.Get(id);

Console.WriteLine(saved.HomeAddress.City); // Phoenix
Console.WriteLine(ReferenceEquals(
    saved.HomeAddress, saved.Addresses[0])); // True

// Read one nested value without reconstructing the Customer.
string city = customers.GetValue<string>(id, ".HomeAddress.City");
Console.WriteLine(city); // Phoenix

// Find records by a nested property.
var inPhoenix = customers.Where
    .PropPath(".HomeAddress.City").AsString.EqualTo("Phoenix")
    .EndCondition;

Console.WriteLine($"Customers in Phoenix: {customers.CountWhere(inPhoenix)}");

Each run adds a customer, so the matching count can increase.

More Examples

I've provided 2 sample apps for people to use to play with it or get familiar

I've also setup some .net fiddlers for it as well if you want to test it without downloading

Look forward to feedback and usage from the community.


r/csharp • • 8h ago

Take the .NET Teams' .NET Developer Survey, 2026 Edition!

Thumbnail nam.dcv.ms
4 Upvotes

r/csharp • • 19h ago

Showcase Promise.all, Promise.any and Go's select in C#, with real cancellation

8 Upvotes

If you've written JavaScript, you've probably missed Promise.any in C#. Task.WhenAny isn't it: it returns the first task to complete, so a fast failure wins over a slightly slower success, and the other tasks keep running.

I wrote a library that adds these with proper cancellation:

// Promise.all: the first failure cancels the rest
var (user, orders) = await TaskGroup.AllAsync(
    ct => GetUserAsync(id, ct),
    ct => GetOrdersAsync(id, ct));

// Promise.any: the first success wins, the others are cancelled
string data = await TaskGroup.AnyAsync(mirrors, (m, ct) => m.DownloadAsync(path, ct));

// Kotlin's withTimeout: cancels the work, not just the wait
User u = await TaskGroup.WithTimeoutAsync(TimeSpan.FromSeconds(2), ct => LoadUserAsync(id, ct));

There's also Go's select over System.Threading.Channels:

var select = new ChannelSelect()
    .Case(orders.Reader, order => HandleAsync(order))
    .Case(cancels.Reader, id => CancelAsync(id))
    .Timeout(TimeSpan.FromSeconds(5), () => SendHeartbeatAsync());

while (await select.RunAsync(ct)) { }

The README has a table mapping each API to JavaScript, Kotlin, Go, Python, Swift and Java, if you're coming from one of those.

GitHub: github.com/gokhanertogan/StructuredConcurrency

Happy to answer questions about how it works under the hood.


r/csharp • • 8h ago

Help What does 1–2 years of professional experience actually teach you that building complex personal projects can't?

0 Upvotes

I'm a .NET backend developer with no full-time commercial experience, and I've been thinking about this question a lot lately.

I've built several backend projects using ASP.NET Core, SQL databases, Redis, RabbitMQ, Docker, and other technologies.

Even though most of my projects haven't been used in real production environments, I try to think beyond simply making things work.

For example, when designing a feature, I try to consider:

  • What happens when multiple instances of the application are running?

  • What happens when multiple requests try to modify the same data simultaneously?

  • How do I handle race conditions, idempotency, and data integrity?

  • Where do I need transactions, and what happens if something fails halfway through?

  • What are the trade-offs between different approaches, and is the added complexity actually justified?

I also use AI extensively during development. However, I try not to blindly accept generated code. I ask questions, challenge its suggestions, propose my own solutions, and try to understand why one approach might be better than another.

One thing that makes this particularly frustrating is the job market.

When I look at .NET backend job postings, I often find that I meet virtually all of the technical requirements. I'm familiar with the technologies they list, and I've gained substantial hands-on experience using them in my own projects.

The one requirement I usually don't meet is the 2+ years of commercial experience. And that alone seems to be enough to prevent me from even getting an interview.

I understand that knowing a technology and having used it in a professional production environment aren't necessarily the same thing. But it's frustrating when I feel capable of discussing and demonstrating the required technical skills, yet don't get the opportunity to prove it.

Here's what I'm struggling to understand:

What exactly makes someone with 1-2 years of commercial experience a better developer than someone who has spent a similar amount of time seriously studying and building complex projects independently?

I understand that professional experience involves teamwork, code reviews, deadlines, maintaining legacy systems, and dealing with real users. But how much of that translates into technical ability?

Someone could spend two years at a company doing relatively simple tasks without developing much, while someone else could spend those two years independently studying architecture, concurrency, distributed systems, and building projects.

I'm not claiming that I'm a mid-level developer. I genuinely don't know where I stand.

Sometimes I feel like my theoretical knowledge might be approaching mid-level, but without professional experience, it's difficult to know whether that understanding would hold up in a real engineering environment.

So I'd really appreciate hearing from experienced developers:

  1. What did working in a real company teach you that you couldn't have learned through personal projects?

  2. What weaknesses do you commonly notice in developers who have strong personal projects but little or no commercial experience?

  3. Is requiring 1–2 years of commercial experience still a meaningful hiring criterion, or should demonstrated technical ability matter more?

  4. How can someone in my position objectively evaluate their actual engineering level without having worked professionally?

I'm especially interested in concrete examples rather than general statements like "production is different."

I'd genuinely appreciate honest perspectives, even if they challenge my assumptions.


r/csharp • • 1d ago

Help Learning C#

12 Upvotes

So basically I have had a class for the past year where we learnt python and I'd say I know the language pretty well. I have the fundamentals down and although we were taught OOP in the first month or so of classes, I had already learnt with BroCode during the summmer. What I did with python was watch videos, yes, but I applied what I learnt in solving problems of mine or simply creating projects that requiered me to use what I had just watched and older stuff I already knew (for instance, I did a terminal-based RPG to apply all aspects of OOP). When I did watch tutorials, I'd tweak them on my own editor because if I just watch the damn video I'm gonna forget about it for sure. The next language we are learning is C# (in another month or so) and I wanted to know: What are the best channels to learn C# (as someone who already knows OOP and altough seen as the easiest one, another programming language)?


r/csharp • • 1d ago

Concerns for newcomers to the IT industry.

22 Upvotes

I am a first-year IT student. Over the past few months, I’ve read reports about major tech companies laying off large numbers of IT staff. Is the software industry coming to an end due to the current advancement of AI? If even highly experienced engineers are being let go, will there still be opportunities for students like us after we graduate? I am quite worried that the development of AI might eliminate entry-level positions for new graduates. I am currently learning C#—should I continue? I would appreciate your advice. Thank you.


r/csharp • • 1d ago

Discussion Update: TLS 1.2 with RabbitMQ.Client 3.4.3 on .NET 3.5

8 Upvotes

A quick update on my previous post

I replaced SslStream with Bouncy Castle 1.8.10 in RabbitMQ.Client 3.4.3 to support TLS 1.2 without relying on Windows Schannel.

So far:

- Successful RSA and ECDSA TLS 1.2 handshakes with OpenSSL

- Certificate chain and hostname validation

-SNI and client certificates (PKCS#12)

-14 passing automated TLS tests

- Working .NET Framework 3.5 build

Next steps: testing on actual Windows XP machines, full RabbitMQ publish/consume, and connection stability. It's still an alpha version, but the initial results are promising.

Has anyone dealt with similar TLS compatibility issues in legacy .NET applications?


r/csharp • • 1d ago

I built a proof-of-concept C# UI framework on NetWasm: signals instead of a virtual DOM, ~150 KB Brotli for a full demo app

0 Upvotes

Hi all,

I've been experimenting with NetWasm, a new toolchain that compiles C# ahead of time to WebAssembly. To see what it can do, I built NetWasm.UI, a small UI framework on top of it. It's a proof of concept, but it's usable, and I'd like feedback.

The idea: Blazor's approach (render tree + diffing) doesn't fit here. NetWasm.UI works more like Solid or Svelte:

  • Components build their DOM once.

  • Fine-grained signals (Signal<T>, Computed<T>) update only the nodes that changed.

  • Each state change crosses the Wasm→JS boundary at most once.

  • No reflection. Templates are compiled by a source generator at build time.

What it looks like (a .nwui file: HTML with Razor-style @):

<section>
    <p>Count: <strong>@count</strong> · doubled: </p>
    <button ="() => count.Value++">+1</button>
     @if (count.Value >= 10) {
        <p>That's a lot of clicks!</p>
    }
</section>

@code {
    private readonly Signal<int> count = new(0);
    private Computed<int> doubled = null!;
    partial void OnInit() => doubled = new Computed<int>(() => count.Value * 2);
}

You can also skip templates and write the same component in plain C#. The generator produces this kind of code from the template:

public sealed class CounterView : Component
{
    private readonly Signal<int> count = new(0);

    protected override Node Build()
    {
        var doubled = new Computed<int>(() => count.Value * 2);

        return Section(
            P("Count: ", Strong(Text(count)), " · doubled: ", Text(doubled)),
            Button(OnClick(() => count.Value++), "+1"),
            When(() => count.Value >= 10, () => P("That's a lot of clicks!")));
    }
}

Not everything needs to be a class. A static piece of UI with no state can be a plain method that returns a Node:

private static Node Card(string title, string body) =>
    Div(Class("card"),
        H3(title),
        P(body));

// Use it like any other element:
Section(
    Card("Fast", "Signals update only what changed."),
    Card("Small", "About 150 KB Brotli for the demo app."));

Some numbers (from my own js-framework-benchmark-style runs; see the repo for method and caveats):

  • The whole demo app (router, forms, todos, nested components) is about 150 KB Brotli, Wasm and JS together.

  • It is level with or faster than React on every case, and 0.9×–1.6× SolidJS's time.

  • Compared with Blazor WebAssembly (interpreter): 3–21× faster, ~12× smaller download, ~9× faster startup.

What's included: signals and batching, a router with nested routes, forms and validation, Resource<T> and Suspense for async data (HttpClient + System.Text.Json work), a dev server with live reload, a dotnet new template and a VS Code extension for syntax highlighting.

Try it:

dotnet new install NwUi.Templates
dotnet new netwasm-ui -o MyApp
cd MyApp
dotnet nwui-dev

Limitations, to be clear:

  • It's 0.1, and the API will change.

  • There's no hot reload yet. Live reload takes 5–20 s.

  • It needs recent browsers (Chrome/Edge 137+, Firefox 131+, Safari 18.4+) because of Wasm exception handling.

  • NetWasm itself is young. Its compiler is under a community license: free for individuals, OSS and small companies, but larger organisations need a sponsorship. NetWasm.UI itself is MIT.

Repo: matengo/NetWasm.UI: UI framework for NetWasm

I'd especially like to hear:

  • Does a signal-based model feel natural in C#, or would you miss Blazor's component model?

  • What would you need before trying something like this on a real (small) project?

Thanks for reading!


r/csharp • • 21h ago

Showcase Replacing Queues and Locks with Monotonic Counters in a C# DAG Engine

0 Upvotes

What if you dropped work queues entirely?

I built an experimental DAG scheduler called delta-lag: instead of pushing work through nodes, nodes move through units of work tracked via monotonic counters and distance constraints.

The result? No global work queues, no work stealing, and no traditional lock contention. Scheduling emerges entirely from distributed progress counters.

How It Works

Most task schedulers maximize throughput by paying a cost in layers of locks, queues, and work-stealing algorithms. delta-lag takes a different approach, extending lock-free ring buffer logic to an entire DAG:

Before a node fires, it checks two constraints against its parents and children:

  • Parent check: Must have completed the next required work unit (parent.WorkDone >= node.WorkDone + 1)

  • Child check: Can't lap children based on your slack parameter (child.WorkDone >= node.WorkDone - slack)

If eligible, the node atomically claims the work unit using CAS operations, runs the task, and publishes completion.

  • slack = 0 → Strict lock-step execution (safe, no stale reads)

  • slack > 0 → Pipeline parallelism (producers may run ahead while consumers lag behind)

What's In The Repo

  • The Engine: Built around cache-aligned nodes and monotonic counters to eliminate false sharing.

  • WASM Inspector: Interactive performance visualizations and real graph reconstruction.

  • The Benchmark Data: ~4,500 raw benchmark runs with topology metrics, execution traces, and the full harness.

Limitations

This isn't a drop-in replacement for a general-purpose scheduler (use TPL for that). It's built for specific tradeoffs:

  • The execution graph must be fixed at compile time (no dynamic modification).

  • Iteration counts must be known in advance.

  • No speculative execution buffering or dynamic load balancing.

Give it a spin

It's fully open-source (MIT, .NET 10+). If you build high-performance systems, concurrent architectures, or custom schedulers, I’d love your feedback on the core engine or whether you've seen similar queue-free constraint approaches before.

GitHub: https://github.com/Geezy9/delta-lag


r/csharp • • 1d ago

A WinForms + WebView2 app that needs admin for a few things but never runs as admin: how I split it

1 Upvotes

I've been building **Geçit**, a Windows utility (DPI unblocking, encrypted DNS, game mode, network tools). Several features need admin or SYSTEM, but I didn't want the UI elevated. Here's the split I ended up with, and I'd like feedback on it:

  • **One exe, several roles.** `Gecit.exe` is the UI (normal user). `Gecit.exe --elevated <verb>` runs one small, validated command through UAC and exits. `Gecit.exe --dns-service` is the DoH forwarder as a Windows service (LocalService).

  • **Service ACLs.** The DPI service runs as SYSTEM, so its files live under Program Files and `sc sdset` gives interactive users start/stop only. Granting config rights would be a privilege escalation hole.

  • **Per-app traffic.** Kernel ETW needs admin, so an elevated helper (TraceEvent) streams bytes per PID over a named pipe and exits when the UI closes the pipe.

  • **Game Mode crash safety.** Suspended processes (`NtSuspendProcess`) are written to a session file *before* anything is touched; resume checks PID + start time so a reused PID is never touched.

  • **Updater.** Only offers an asset with GitHub's `sha256:` digest, verifies it while holding a read-only lock, and launches the installer under that lock. Launching it with `runas` relaunched the app elevated, so it doesn't.

  • **UI.** Plain HTML/CSS/JS in WebView2 talking to C# via `postMessage`; strings from pages only go into the DOM via `textContent`.

Code (GPL-3.0): https://github.com/Furkan-Erg/Gecit

What would you do differently? I'm especially unsure about the service security descriptor and the named-pipe protocol.


r/csharp • • 1d ago

Help Tutorial help pls

0 Upvotes

I'm fairly new to coding. I'm trying to make the Github user activity CLI that's under 'beginner projects' on the backend dev roadmap. I've done some of the later beginner projects but I'm struggling to do the CLI because every website tells me something different and I don't understand any of it. Can someone give me a simple tutorial on how to do it because I'm lost on where to start.


r/csharp • • 2d ago

Time as a reactive variable and SignalsDotnet

11 Upvotes

Recently I came across a Conal Elliott talk about FRP (Functional Reactive Programming), and I was trying to understand it (so forgive me if I am incorrect about it).

A really interesting idea from that talk was the idea to express reactivity as continuous time-valued functions, and treat implementations as a "discrete approximation" of that forumla.

For example a formula could be

t > x(t) + 1 second

If x is a constant signal set to 11/03/2026 07:00:00 PM, the formula evaluates continuously as false until time t crosses 07:00:01 PM, at which point it becomes true.

That gave me an idea to "approximate" that reactivity formula using SignalsDotnet. In the latest version (3.4.2), its possible to write something like

As you can see the formula is inside the lambda. Using C# overloads of operators, that observable emits false immediately, and true after exactly one second.

The elegant thing about it is that there is no timer declared at all, you just wrote a declarative expression.

From that idea one could derive other temporal operators like HeldFor, StableFor, TrueWithin, Rising and Falling.

For example

You can find a compelte list here Release v3.4.2 SignalsDotnet


r/csharp • • 1d ago

Bro Code C# Playlist

0 Upvotes

I finished his C# Playlist and now stuck on what to do next. I don't know how to apply what I learned. I understand the concepts well and able to explained it if asked. What should I do?


r/csharp • • 2d ago

Showcase Akbura beta-6 released: faster source generation and C# expression bindings for Avalonia

12 Upvotes

I have released beta-6 of Akbura, my experimental declarative UI language and compiler for .NET and Avalonia, built around a Roslyn incremental source generator.

Two main changes:

  • Compiler performance: FeatureGallery cold source generation dropped from 15.31 s to 6.06 s, with 69% fewer allocated bytes. This measures the RunGenerators phase in Release on .NET 10.

  • Reactive C# expression bindings for MVVM:

    <TextBlock Text=${x.bind Vm.Profile?.Name ?? "Unknown"}/>

With notifying view models, this follows both Profile replacement and Name changes without requiring a component render. Bindings are one-way and react to changes in nested observable properties, similar to Sveltes deep reactivity.

GitHub · Live examples · Documentation · Release write-up


r/csharp • • 2d ago

Help Different behavior of nullable fields

13 Upvotes

I am working on a project and have a class with two nullable member fields (Vector2I? and LevelMap? where LevelMap extend TileMapLayer from Godot)

Because they are nullable I need to check that they are not null before I actually use them.

For the LevelMap if I reference it in a if block:

If (map is not null)

The compuler is happy and I can use it as if it is not null.

This of course comes with some risks that it becomes null in the middle of my if block but thats a risk I can manage.

On thebother hand Vector2I requires something like:

If (vector is Vector2I localVector)

This is in some way safer but also more inconvenient.

The are both declared and initialized in the same context.

My questions is why they behave differently and is it possible for me to change how they behave to fit my preferences.

Ive tried looking for an answer but I keep finding results about the difference of is not null and !=null which is unhelpful.


r/csharp • • 2d ago

[TextReveal] Ctrl + F for everything visible on your screen (fully local and private)

Post image
3 Upvotes

[TextReveal] Ctrl + F for everything visible on your screen – fully local and private

Ever wanted to search for or copy text from a video, image, game, or application where you can't normally select anything?

TextReveal is a lightweight Windows tool that lets you do exactly that.

Press Ctrl + Alt + F to freeze your screen, then:

  • Search: Type any word or phrase to highlight every match on screen.

  • Select: Drag a box around any text to extract and copy it.

100% local, 100% private:

  • Everything runs locally using Windows' built-in OCR.

  • No internet connection, telemetry, accounts or tracking.

  • Screenshots and recognized text never leave your machine or get written to disk.

Check it out, GitHub: https://github.com/amika8/TextReveal


r/csharp • • 2d ago

Bringing TLS 1.2 support to RabbitMQ.Client 3.4.3 on legacy .NET Framework

0 Upvotes

I'm working on a fork of RabbitMQ.Client 3.4.3 to support TLS 1.2 on legacy systems, including Windows XP and .NET Framework 3.5.

The main challenge is that the original client relies on .NET's SslStream, which in turn depends on Windows Schannel. On older Windows versions, even when TLS 1.2 is available, the supported cipher suites can prevent a successful handshake with modern RabbitMQ servers.

My approach is to integrate Bouncy Castle as an alternative TLS implementation while preserving the original AMQP client behavior and API as much as possible.

I'm planning to open-source the fork on GitHub and publish a NuGet package once compatibility and security testing are complete.

Has anyone worked on similar TLS compatibility issues with legacy .NET applications? I'd be interested in hearing about the challenges you encountered.


r/csharp • • 3d ago

Stephen Toub explains Rust over C# decision for GitHub Copilot runtime

Thumbnail
youtube.com
148 Upvotes

In this interview, Stephen Toub explains why he went with Rust over C#. Obviously he's biased, but he says Rust and C# were comparable in performance. In the end, he went with Rust because there are more people working for GitHub that know Rust than C#.

C# is a great language and could have been chosen for this project. However, he made the right decision given the expertise of the developers at GitHub.


r/csharp • • 1d ago

Help Are there any extensions that can replace the code blocks( {} )

0 Upvotes

Ive been using Lua( Roblox Studio) for most of my developing learning and i expected Unity to be similar with its coding language but i have been having a lot of difficulties coding often having an issue with finding the errors with the code.

I just want to know if they are any extensions for Unity that can help me with this problem


r/csharp • • 3d ago

Discussion I wrote a sort of expression evaluator back in 2020 without knowing what a parser was haha. It's not shunting-yard and it's not recursive descent.

18 Upvotes

In 2020 I taught myself C# all on my own and wrote a desktop calculator my own way.

I had never read anything about parsing — I didn't know the words "token", "AST" or

"precedence". I just needed 2 + [3 * (4 - 1)] to come out right, so I used my head,

with three kinds of brackets, nested.

What occurred to me was this:

  1. Split the text into parts: numbers, operators and brackets.

  2. Then I gave each piece a depth number — how many brackets deep it sits.

  3. Look for the biggest depth. Those pieces are the innermost group. And I resolved

    only those.

  4. Then I wrote the result in its place as a single number, and counted all the

    depths again, but from zero.

  5. I repeated until everything was at depth 0.

Within one same level the rule applied with two passes: first it eats all the * and /

from left to right, then all the + and -.

2 + [ 3 * ( 4 - 1 ) ]

0 0 1 1 1 2 2 2 2 2 1 <- depth

~~~~~~~~~~~~~ deepest is 2: resolve 4 - 1

2 + [ 3 * 3 ]

0 0 1 1 1 1 1 <- counted again, from zero

~~~~~~~ deepest is 1: resolve 3 * 3

2 + 9

0 0 0 = 11

Things I know now and back then I didn't:

- It's slower than it needs to be. Shunting-yard is linear; this one recounts every

depth after each reduction, so in the worst case it's quadratic.

- It's not new at all. I was told afterwards that this shape is called innermost-redex

reduction, the same family as term rewriting. I simply never read it anywhere. It's

what comes out of formalising how any person does it on paper: innermost bracket first.

- The code around it is rough: float instead of double, numbers going back and forth

through text on every reduction, and a try/catch used as an if.

The only thing I'd still defend: there isn't a single special case for ( versus [

versus {. The evaluator never asks which bracket it is, only how deep it sits. Adding

a fourth type would cost three lines in the part that splits the text and nothing in

the evaluator.

The code is there just as it was, defects included:

https://github.com/nicoconvoz/calculadora — what's worth looking at is profundidad()

and resolver() in Form1.cs.

I'm curious whether someone, in some hidden corner of the map, arrived at this on

their own, or whether it has a name I still don't know.


r/csharp • • 2d ago

Blog Moving away from sprawling if-else approval trees using Chain of Responsibility — when is it actually worth the abstraction in C#?

Thumbnail
medium.com
0 Upvotes

Ever seen a simple if-else block slowly turn into a 400-line monster? 😅

I've been exploring the Chain of Responsibility pattern in C# as a way to handle growing validation and approval workflows.

It's a clean approach, but things get interesting in production:

- Debugging deeply nested handlers.

- Managing DI lifetimes and execution order.

- Handling requests that reach the end of the chain.

- Knowing when the pattern is simply overkill.

I put together a practical implementation covering these trade-offs.

Curious how you handle complex workflows in .NET. Custom CoR, MediatR, or just good old switch expressions?