Sdílet prostřednictvím


Omezení parametrů typů (Průvodce programováním v C#)

Při definování Obecná třída můžete použít omezení druhů typů, které klientský kód můžete použít pro argumenty typu, když ji vytvoří instanci třídy.Pokud kód klienta se pokusí vytvořit instanci třídy pomocí typu Nepovolené omezení, výsledkem je chyba při kompilaci.Tato omezení se nazývají omezení.Omezení jsou určeny pomocí where kontextové klíčové slovo.Následující tabulka obsahuje šest typů omezení:

Omezení

Description

kde T: struct

Argument typu musí být typu hodnoty.Libovolný typ kromě hodnoty Nullable může být zadán.Další informace naleznete v tématu Použití typů s povolenou hodnotou Null (Průvodce programováním v C#).

kde T: Třída

Argument typu musí být typu odkazu; To platí také pro třídy, rozhraní, delegáta nebo typ pole.

kde T: new()

Argument typu musí mít veřejný konstruktor bez parametrů.Při použití jiných omezení new() omezení musí být zadán jako poslední.

kde T: < základní název třídy >

Argument typu musí být nebo odvodit ze zadané základní třídy.

kde T: < název rozhraní >

Argument typu musí být nebo implementují zadané rozhraní.Lze zadat více omezení rozhraní.Omezující rozhraní může být také obecný.

kde T: U

Typ argumentu pro t musí být nebo odvodit od argumentu pro U.

Proč používat omezení

Pokud chcete zkontrolovat položky obecného seznamu určete, zda je platný nebo porovnat některé další položky, musíte mít kompilátor některé zaručit, že provozovatel nebo musí volat metodu bude podporováno jakýkoliv typ argument, který může být zadán kód klienta.Tato záruka je získán použitím jedno nebo více omezení pro vaše definice třídy obecný.Například základní třída omezení kompilátoru sděluje, že pouze objekty tohoto typu nebo odvozených od tohoto typu bude použit jako argumenty typu.Tato záruka Jakmile kompilátor umožňuje typu obecný třídy volané metody.Omezení zásad pomocí kontextové klíčové slovo where.Následující příklad kódu ukazuje přidáme do funkce GenericList<T> třídy (v Úvod do obecných typů (Průvodce programováním v C#)) použitím omezení základní třídy.

public class Employee
{
    private string name;
    private int id;

    public Employee(string s, int i)
    {
        name = s;
        id = i;
    }

    public string Name
    {
        get { return name; }
        set { name = value; }
    }

    public int ID
    {
        get { return id; }
        set { id = value; }
    }
}

public class GenericList<T> where T : Employee
{
    private class Node
    {
        private Node next;
        private T data;

        public Node(T t)
        {
            next = null;
            data = t;
        }

        public Node Next
        {
            get { return next; }
            set { next = value; }
        }

        public T Data
        {
            get { return data; }
            set { data = value; }
        }
    }

    private Node head;

    public GenericList() //constructor
    {
        head = null;
    }

    public void AddHead(T t)
    {
        Node n = new Node(t);
        n.Next = head;
        head = n;
    }

    public IEnumerator<T> GetEnumerator()
    {
        Node current = head;

        while (current != null)
        {
            yield return current.Data;
            current = current.Next;
        }
    }

    public T FindFirstOccurrence(string s)
    {
        Node current = head;
        T t = null;

        while (current != null)
        {
            //The constraint enables access to the Name property. 
            if (current.Data.Name == s)
            {
                t = current.Data;
                break;
            }
            else
            {
                current = current.Next;
            }
        }
        return t;
    }
}

Omezení umožňuje Obecná třída používat Employee.Name vlastnost protože všechny položky typu t je zaručena buď Employee nebo objektu, který dědí z Employee.

Lze použít více omezení pro stejný parametr typu a samotných omezení mohou být obecné typy takto:

class EmployeeList<T> where T : Employee, IEmployee, System.IComparable<T>, new()
{
    // ...
}

Omezení parametru typu zvýšíte počet povolených operací a nejsou podporovány všechny typy v hierarchii dědičnosti a omezující typ volání metody.Proto při návrhu obecného třídy nebo metody, pokud jste se veškeré operace na členy obecný rámec jednoduché přiřazení nebo voláním jakékoli metody nejsou podporovány System.Object, budete muset použít omezení parametru typu.

Při použití where T : class omezení, vyhnout == a != operátory pro parametr typu protože těchto operátorů bude test identity odkaz, není pro hodnotu rovnosti.To platí i v případě, že tyto operátory jsou přetížené typu, který se používá jako argument.Následující kód ilustruje tento bod; Přestože je false výstup String třídy přetížení == operátor.

public static void OpTest<T>(T s, T t) where T : class
{
    System.Console.WriteLine(s == t);
}
static void Main()
{
    string s1 = "target";
    System.Text.StringBuilder sb = new System.Text.StringBuilder("target");
    string s2 = sb.ToString();
    OpTest<string>(s1, s2);
}

Důvodem tohoto chování je, že v době kompilace, kompilátor pouze ví že t je typ odkazu a proto musí používat výchozí operátory, které jsou platné pro všechny typy odkazů.Pokud musí zkouška hodnoty rovnosti doporučený způsob je také použít where T : IComparable<T> omezení a implementace, která rozhraní do třídy, která bude použita k vytvoření Obecná třída.

Omezení více parametrů

Omezení lze použít více parametrů a více omezení na jeden parametr, jak ukazuje následující příklad:

class Base { }
class Test<T, U>
    where U : struct 
    where T : Base, new() { }

Neomezeně parametry typu

Zadejte parametry, které obsahují žádné omezení, například veřejné třídy t SampleClass<T>{}, se nazývají parametry typu neomezeně.Parametry typu neomezeně mají následující pravidla:

  • != a == operátory nelze použít, protože není zaručeno, že konkrétní typ argumentu bude podporovat tyto operátory.

  • Mohou být převedeny do a z System.Object nebo explicitně převést na jakýkoli typ rozhraní.

  • Můžete porovnat s null.Pokud neomezeně parametr je ve srovnání s null, porovnání vždy vrátí hodnotu false, pokud je argument typ hodnotu typu.

Parametry typu jako omezení

Použití parametru obecný typ omezení je užitečné při členské funkce s vlastní typ parametru má omezení parametru typu parametru typ, jak je znázorněno v následujícím příkladu:

class List<T>
{
    void Add<U>(List<U> items) where U : T {/*...*/}
}

V předchozím příkladu T je typ omezení v souvislosti Add metoda a parametrem typu neomezeně v kontextu List třídy.

Parametry typu lze použít také jako omezení v definicích Obecná třída.Všimněte si, že parametr typu musí být deklarována v rámci lomených závorkách spolu s jinými parametry typu:

//Type parameter V is used as a type constraint. 
public class SampleClass<T, U, V> where T : V { }

Užitečnost parametry typu jako omezení s obecnou tříd je velmi omezené, protože kompilátor může převzít nic o parametr typu s výjimkou, že pochází z System.Object.Parametry typu použijte jako omezení obecného tříd v situacích, ve kterých chcete vynutit vztahu dědičnosti mezi dvěma parametry typu.

Viz také

Referenční dokumentace

Úvod do obecných typů (Průvodce programováním v C#)

Obecné třídy (Průvodce programováním v C#)

new – omezení (Referenční dokumentace jazyka C#)

System.Collections.Generic

Koncepty

Průvodce programováním v C#