Title here
Summary here
Starting with version 1.0, C# has added support for *generics*.
As an example of a generic method, `SlicesIndex` takes an `IEnumerable<T>` of any type `T` that implements `IEquatable<T>` and an element of that type, and returns the index of the first occurrence of `v` in `s`, or -1 if not present. The `IEquatable<T>` constraint means that we can compare values of this type with the `Equals` method.
```csharp
public static int SlicesIndex<T>(IEnumerable<T> s, T v) where T : IEquatable<T>
{
int index = 0;
foreach (var item in s)
{
if (item.Equals(v))
{
return index;
}
index++;
}
return -1;
}
As an example of a generic type, List<T>
is a singly-linked list with values of any type.
public class List<T>
{
private Element<T> head;
private Element<T> tail;
private class Element<T>
{
public Element<T> Next { get; set; }
public T Value { get; set; }
}
public void Push(T v)
{
if (tail == null)
{
head = new Element<T> { Value = v };
tail = head;
}
else
{
tail.Next = new Element<T> { Value = v };
tail = tail.Next;
}
}
public IEnumerable<T> AllElements()
{
var current = head;
while (current != null)
{
yield return current.Value;
current = current.Next;
}
}
}
Here’s how we can use these generic types and methods:
class Program
{
static void Main(string[] args)
{
var s = new List<string> { "foo", "bar", "zoo" };
Console.WriteLine($"index of zoo: {SlicesIndex(s, "zoo")}");
var lst = new List<int>();
lst.Push(10);
lst.Push(13);
lst.Push(23);
Console.WriteLine($"list: [{string.Join(", ", lst.AllElements())}]");
}
}
When invoking generic methods, we can often rely on type inference. Note that we don’t have to specify the type for T
when calling SlicesIndex
- the compiler infers it automatically.
The output of this program would be:
index of zoo: 2
list: [10, 13, 23]
This example demonstrates how generics in C# allow us to write flexible, reusable code that works with different types while maintaining type safety.