---
title: Generics
slug: generics
createdAt: 2021-06-28T17:12:43.000Z
---

Shift has strong generic support. A generic type allows a user to define a template/container for a set of behavior that will operate based on a passed in type. These passed in types are called Type Arguments. The type system is fully generic aware so different instances of the generic type will be understood as different types.

List\<T> in C# is probably one of the most common examples in C#. It is a list of some type. It holds an indefinite number of items in a specific order, each of those items being guarenteed to be whatever type T is.

This saves us the programmer time, because we do not need to program a list type manually for every thing we may want to add to a list. Furthermore it's generally more safe than the non-generic version such as List, which is just a list of anything. Rarely do you want to be able to construct a list of literally anything and work with that. By specifying the type, you can convey intent and get the type safety benefits that the compiler can provide.

## Type Arguments

When declaring a type, you can specify a type's arguments at the same time.

:::BlockQuote
service Example\<Targ1, Targ2>
\{
&#x20; ...
}
:::

When specifying the type's name you declare that there are type arguments via the \< > arguments. This takes in an array of identifiers that correspond to each Type arguement. This is the closest mechanism that Shift has to what would be templates or containers in other languages.

`Targ1` and `Targ2` are both placeholders and references to what Type will be specific at declaration time for an Example variable.

Here's what specifying this would look like.

```csharp
var ex = new Example<int, string>();
Example<bool,bool> ex2;

service Foo
{
    Example<int,int> BuildExample()
    {
        return new Example<int,int>();
    }

    Example<int,bool> GenericOnBothSide(Example<bool, bool> exIn)
    {
        var translated = translatorFunction(exIn);//Produces a Example<int,bool>
        return translated;
    }
}
```

The only new concept above is when referring a generic type, you have to supply the arguments.&#x20;

On the definition side of the Example service the type has a type argument as the placeholder. This is often referred to as an open generic. The generic's type is open to definition still, we have placeholders so it's not concrete yet.

All of the code that would use our service Example must fully specify all of the type arguments thus "closing" the type. Referred to as a closed generic.

The most important thing to remember, is anywhere a type can be supplied a generic type is a valid option to pass.

## Variance



