Несколько ограничений
Ограничения для одного параметра перечисляют
через запятую: сначала класс, struct или
базовый тип, затем интерфейсы, в конце -
new(),
если он нужен. Типичная запись
where T : class, IComparable<T>, new()
требует ссылочный тип с сравнением и
публичным конструктором без параметров.
Синтаксис
class Sorter<T>
where T : class, IComparable<T>, new()
{
}
Пример
Давайте создадим экземпляр через new T()
при нескольких ограничениях:
using System;
class CodeRow : IComparable<CodeRow>
{
public string Text;
public CodeRow()
{
Text = "abcde";
}
public int CompareTo(CodeRow? other)
{
return string.Compare(Text, other?.Text, StringComparison.Ordinal);
}
}
class Maker<T> where T : class, IComparable<T>, new()
{
public T Build() => new T();
}
class Program
{
static void Main()
{
var maker = new Maker<CodeRow>();
Console.WriteLine(maker.Build().Text);
}
}
Результат выполнения кода:
"abcde"
Пример
Давайте сравним два объекта через
IComparable<T>:
using System;
class NumRow : IComparable<NumRow>
{
public int Num;
public NumRow() { }
public int CompareTo(NumRow? other)
{
return Num.CompareTo(other?.Num ?? 0);
}
}
class Pick<T> where T : class, IComparable<T>, new()
{
public string MinLabel(T left, T right)
{
return left.CompareTo(right) <= 0 ? "left" : "right";
}
}
class Program
{
static void Main()
{
var pick = new Pick<NumRow>();
var left = new NumRow { Num = 1 };
var right = new NumRow { Num = 3 };
Console.WriteLine(pick.MinLabel(left, right));
}
}
Результат выполнения кода:
"left"
Пример
Давайте добавим к class ещё интерфейс
и вызовем его метод:
using System;
interface ICode
{
string GetCode();
}
class Token : ICode, IComparable<Token>
{
public string Code = "12345";
public Token() { }
public string GetCode() => Code;
public int CompareTo(Token? other)
{
return string.Compare(Code, other?.Code, StringComparison.Ordinal);
}
}
class Reader<T> where T : class, ICode, new()
{
public string Read(T item) => item.GetCode();
}
class Program
{
static void Main()
{
var reader = new Reader<Token>();
Console.WriteLine(reader.Read(new Token()));
}
}
Результат выполнения кода:
"12345"
Смотрите также
-
ограничение new(),
которое часто ставят последним в списке -
ограничение базы,
которое можно комбинировать с интерфейсами -
интерфейс
IComparable,
который задаёт порядок дляT -
ограничение class,
которое часто идёт первым в цепочке