Generic types
class Pair<T, U>
{
public T Item1 { get; private set; }
public U Item2 { get; private set; }
public Pair(T item1, U item2)
{
Item1 = item1;
Item2 = item2;
}
}
var p1 = new Pair<int, int>(1, 2);
var p2 = new Pair<int, double>(1, 42.99);
var p3 = new Pair<string, bool>("true", true);
public abstract class Shape<T>
{
public abstract T Area { get; }
}
public class Square : Shape<int>
{
public int Length { get; set; }
public Square(int length)
{
Length = length;
}
public override int Area => Length * Length;
}
public class Square<T> : Shape<T>
{
public T Length { get; set; }
public Square(T length)
{
Length = length;
}
/* ERROR: Operator '*' cannot be applied to operands
of type 'T' and 'T' */
public override T Area => Length * Length;
}
Variant generic interfaces
- A covariant type parameter is declared with the
out
keyword and allows an interface method to have a return type that is more derived than the specified type parameter. - A contravariant type parameter is declared with the
in
keyword and allows an interface method to have a parameter that is less derived than the specified type parameter.
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
public interface IEnumerable<out T> : IEnumerable
{
IEnumerator<T> GetEnumerator();
}
IEnumerable<string> names =
new List<string> { "Marius", "Ankit", "Raffaele" };
IEnumerable<object> objects = names;
public interface F
{}
public class FF : F
{}
F<object> str = new FF<string>();
Generic methods
class CompareObjects
{
public bool Compare<T>(T input1, T input2)
{
return input1.Equals(input2);
}
}
struct Point<T>
where T : struct,
IComparable, IComparable<T>,
IConvertible,
IEquatable<T>,
IFormattable
{
public T X { get; }
public T Y { get; }
public Point(T x, T y)
{
X = x;
Y = y;
}
}