Udostępnij za pośrednictwem


Ograniczenia parametrów typu (Podręcznik programowania C#)

Podczas definiowania klasą rodzajową można zastosować ograniczenia do rodzajów typów, które kod klienta można użyć dla argumentów typu, gdy metoda tworzy klasę.Jeśli kod klienta próbuje utworzyć wystąpienia klasy przy użyciu typu, który nie jest dozwolony przez ograniczenie, wynikiem jest błąd w czasie kompilacji.Ograniczenia te są nazywane ograniczeń.Warunki ograniczające są określane za pomocą where kontekstowe słowa kluczowego.Poniższa lista zawiera sześć typów ograniczeń:

Ograniczenie

Opis

gdzie T: struct

Argument typu musi być typu wartości.Wartość dowolnego typu, z wyjątkiem Nullable może być określony.Zobacz Przy użyciu typu null (C# Programming Guide) Aby uzyskać więcej informacji.

gdzie T: klasa

Argument typu musi być typem odwołania; dotyczy to również do klasy, interface, pełnomocnik lub typ tablicy.

gdzie T: new()

Argument typu musi mieć publicznego konstruktora bez parametrów.Używany wraz z innych ograniczeń, new() ograniczenie musi być określone ostatnio.

gdzie T: < base Nazwa klasy >

Argument typu muszą być lub pochodzić od określonej klasy podstawowej.

gdzie T: < interface Nazwa >

Argument typu muszą być lub wykonania określonego interfejsu.Można określić wiele ograniczeń interfejsu.Można także rodzajowy interfejs ograniczający.

gdzie T: U

Argument typu dostarczone dla t musi być lub pochodzić od argument podany dla U.

Do czego służy ograniczenia

Jeśli chcesz sprawdzić element rodzajowy liście ustalić, czy jest nieprawidłowa lub porównać go w innym elemencie, kompilator musi mieć niektóre gwarantuje, że operator lub metoda ma wywoływać będą obsługiwane przez którykolwiek z argumentów typu, określonej przez kod klienta.Gwarancja ta uzyskuje się poprzez zastosowanie jednego lub więcej ograniczeń w Państwa definicji klasą rodzajową.Na przykład ograniczenie klasy bazowej informuje kompilator, że tylko obiekty tego typu lub pochodzące z tego typu będą używane jako argumenty typu.Gdy kompilator ma gwarancji, umożliwiają metody tego typu ma być wywoływana w klasie rodzajowej.Ograniczenia są stosowane przy użyciu kontekstowe słowa kluczowego where.Poniższy przykład kodu pokazuje funkcji, dodamy do GenericList<T> klasy (w Wprowadzenie do generyczne (Podręcznik programowania C#)) przez zastosowanie ograniczenia klasy podstawowej.

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;
    }
}

Ograniczenie umożliwia rodzajowy klasy Employee.Name właściwości, ponieważ wszystkie elementy typu t gwarantowana jest ich albo Employee lub obiektu, która dziedziczy z Employee.

Wiele ograniczeń mogą być stosowane do tego samego parametru typu i ograniczeń, same mogą być typy rodzajowe w następujący sposób:

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

Ograniczenia parametru typu, zwiększenie liczby operacji dopuszczalne i wywołania metody do działań wspieranych przez typ ograniczający i wszystkie rodzaje ujęte w swojej hierarchii dziedziczenia.W związku z tym, podczas projektowania klas rodzajowych lub metody, jeśli będzie się wykonaniem każdej operacji na rodzajowy członków poza proste przypisanie lub wywołanie każdej metody, które nie są obsługiwane przez System.Object, trzeba będzie zastosować ograniczenia parametru typu.

Przy stosowaniu where T : class ograniczenie, uniknąć == i != podmioty gospodarcze na parametr typu ponieważ tych operatorów spowoduje przetestowanie tożsamości odniesienia, nie dla wartości równości.Jest tak, nawet jeśli te operatory są przeciążone w polu Typ, który jest używany jako argumentu.Poniższy kod ilustruje tę sytuację; Mimo że dane wyjściowe są fałszywe String klasy overloads == operatora.

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);
}

Przyczyną tego zachowania jest, że w czasie kompilacji, kompilator tylko wie, że t jest typem odwołania i dlatego musi korzystać z domyślnych operatorów, które są ważne dla wszystkich typów odniesienia.Jeśli należy przeprowadzić test na wartość równości, zalecanym sposobem jest również stosuje się where T : IComparable<T> ograniczenie i wdrożenia, że interfejs w dowolnej klasy, która będzie używana do konstruowania klasą rodzajową.

Ograniczanie wiele parametrów

Wiele parametrów i ograniczenia wiele do jednego parametru, można zastosować ograniczenia, jak pokazano w następującym przykładzie:

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

Parametrów typu o nieokreślonej długości

Wpisz parametry, które mają nie ograniczeń, takich jak t w public class SampleClass<T>{}, są nazywane parametrów typu o nieokreślonej długości.Parametrów typu niepowiązany mają następujące zasady:

  • != i == nie można używać operatorów, ponieważ nie ma żadnej gwarancji, że konkretny typ argumentu będzie obsługiwać tych operatorów.

  • Mogą być konwertowane, do i z System.Object lub jawnie są konwertowane na dowolny typ interfejsu.

  • Można porównać do null.Jeśli parametr o nieokreślonej długości jest porównywany z null, porównanie zawsze zwraca wartość false, jeśli argument Typ jest typ wartości.

Parametrów typu jako warunki ograniczające

Wykorzystanie parametr typu rodzajowego jako ograniczenie jest użyteczna, gdy funkcja Członkowskie własnej parametru typu ma ograniczenie tego parametru z parametrem typu zawierające typ, jak pokazano w następującym przykładzie:

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

W poprzednim przykładzie T jest ograniczenie typu w kontekście Add metody i parametrem typu bez ograniczeń w kontekście List klasy.

Parametrów typu może również służyć jako ograniczeń w definicji klasy rodzajowe.Należy zauważyć, że parametr typu muszą być zadeklarowane wewnątrz nawiasy wraz z innych parametrów typu:

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

Użyteczność parametrów typu jako ograniczenia z klas rodzajowych jest bardzo ograniczona, ponieważ kompilator może przyjmować nic na temat parametru typu z wyjątkiem, że pochodzi on z System.Object.Używać parametrów typu jako ograniczeń klas rodzajowych w scenariuszach, w których chcesz wymusić dziedziczenie relacji między dwoma parametrów typu.

Zobacz też

Informacje

Wprowadzenie do generyczne (Podręcznik programowania C#)

Klas rodzajowych (Podręcznik programowania C#)

nowe ograniczenie (C# odniesienia)

System.Collections.Generic

Koncepcje

Podręcznik programowania C#