David Vedvick

Notes

My Ideal C#-Like Language

Some of these ideas could live with the current language, some would be drastic changes.

An on keyword for use after an await statement

To make it trivial to switch your synchronization context, an on keyword. Usage:

var updatedValue = await service.GetValue() on UiSynchronizationContext;

I first had this idea in 2022 so I've been on this one for a while.

Easy Implementation of Delegation

If you've been doing this programming thing for a while, you've likely come across the idea of composition over inheritance, that is, prefer delegating implementation to another type instead of inheriting it from a sub-type. Kotlin provides this capability with the by keyword, which seems fine to me. In C#:

interface IAccess
{
    Task<Value> GetValue();

    Task SetValue(Value value);
}

class NetworkAccess(HttpClient httpClient) : IAccess
{
    public Task<Value> GetValue()
    {
        var response = await httpClient.GetJson<Value>();
        return response;
    }

    public Task SetValue(Value value)
    {
        var response = await httpClient.PostJson(value);
    }
}

class CachedAccess(ICache cache, IAccess innerAccess) : IAccess by innerAccess
{
    public Task<Value> GetValue()
    {
        var response = await innerAccess.GetValue();
        cache.Set(key, response);
        return response;
    }

    // SetValue is automatically delegated to innerAccess...
}

Even better would be if we could have automatic decoration. This is a tougher one, how do we handle the infinite number of method combinations? Maybe visitors are a way?

Public Methods Async By Default

In the spirit of more extensive language additions, all public methods should be async by default. A developer should always assume that public methods don't complete immediately. A developer has to instead declare a method sync to state that the method executes immediately. Example:

interface IAccess {
    Value GetValue();
    sync Value GetValueImmediately();
}

var value = await access.GetValue();
var value = access.GetValueImmediately();

What I like about this idea is that method "coloring" works in reverse: the writer of a method has to instead say "this method executes immediately with no I/O access, no computations on another thread", since in the real world, all operations execute asynchronously. One consequence of this idea is that the Task type is hidden, and I do not like hiding "magic" too much, so this definitely has its flaws. Maybe the underlying Task/Promise could be exposed via reflection?

Public Properties Observable By Default

This is another thing that Kotlin/Jetpack Compose sort of has with Mutable State and snapshotFlow, but since it's not a default, you have to kind of guess whether a property is observable or not. In my new language I propose that properties are observable by default. The properties wouldn't need be an IObservable and take on all the baggage of that type, they could just implement IAsyncEnumerable. Example:

class Person {
    public string Name { get; set; }
}

var person = new Person();

var updateNameTask = Task.Run(() => {
    person.Name = "Bob";
    person.Name = "David";
});

await foreach (var name in person.Name)
{
    // Prints "Name: Bob" and then "Name: David"
    Console.WriteLine($"Name: {name}");
}

await updateNameTask;

But you should also just be able to read the current value (see the Interaction State primitive), so you should also be to just call it like a normal property:

class Person {
    public string Name { get; set; } = "John";
}

var person = new Person();
// Prints "John"
Console.WriteLine($"Name: {person.Name}");

Note posted on Monday, December 22, 2025 7:43 AM CST - link