Hyston blog
About • Archive • RSS

Dynamic

February 14, 2022

I’m writing on C# for 5 years now and keep finding things, that are not widely used, but they are exist already for a long time. Just recently I found the need of dynamic keyword. Usually new variables are defined with var or with value type directly:

Foo foo = new Foo();
var foo = new Foo();

These are actually two identical lines, compiler would define actual type on second lane from right-hand operator.

But what if type is unknown in compile type? I have met a problem, where actual type is created by external parameter - and there is no common interface that can be used to aggregate possible types. In these uncommon scenarios dynamic can be very handy.

Suppose, we have a three types:

public record TypeA(string A);
public record TypeB(string B);
public record TypeC(string C);

Then we can declare a function, which return any of this types by random:

dynamic GetRandomType(Random random) => random.Next(3) switch
{
    0 => new TypeA("a"),
    1 => new TypeB("b"),
    2 => new TypeC("c"),
    _ => throw new Exception("out of random range")
};

By making dynamic return type, we tell a compiler, that he should not care, which type it actually is. Problem here in that compiler agreed and skip any further compile-time checking:

var random = new Random();
var result = GetRandomType(random);
result.DoSomething(); // We would get runtime error here

A good thing is, that actual type is available in run time and overloading works even with dynamic type:

public class Foo
{
    public static void Do(TypeA obj) => Console.WriteLine($"Do a: {obj.A}");
    public static void Do(TypeB obj) => Console.WriteLine($"Do b: {obj.B}");
    public static void Do(TypeC obj) => Console.WriteLine($"Do c: {obj.C}");
}
Foo.Do(result); // correct function would be called, based on result type

This can be very handful for places, where actual behaviour is unknown beforehand. As example, I wrote a event parser, where each event contain a enum with event type and object payload. And for each actual event the payload would be a completely different DTO, as well as event handlers would have completely different behaviour.


Next entry → ← Prev entry