Skip to main content


Generics in Evolve are closer to the C++ concept of templates than the C# idea of generics.

When a template declares itself as generic, the generic parameters given act as placeholders for a type name. This means that you can do things with them that C# normally does not allow. Here is an example of a slider element that has a generic <T> type. For this example our slider could represent T as any numeric value such float or int or double.

Let's say we want our slider to have default parameters where the minValue is equal to the smallest number representable by type T. Usually in C# we'd use float.MinValue and friends to represent this. We want our template to work with different number types, not just float. Normally in C# this wouldn't be possible without a lot of trickery. In Evolve, because generics are just type name aliases, we can express this simply as T.MinValue or T.MaxValue. We can even go further and call static methods on the T type such as T.Parse().

Unlike in C#, Evolve's generics do no have the concept of constraints (the where clause in C#). This means that if you try to do a operation on T that is not defined, you'll get a compile error.

template RangeSlider<T> {

required T value;
optional T minValue = T.MinValue;
optional T maxValue = T.MaxValue;

render {
// content here, assume value is clamped between minValue and maxValue