Aracılığıyla paylaş


Genel Arabirimler (C# Programlama Kılavuzu)

Çoğunlukla, genel koleksiyon sınıfları, veya koleksiyon öğeleri temsil eden sýnýflarla arabirimler tanımlamak yararlıdır.Generic arabirimlerden gibi kullanmasına olanak generic sýnýflarý için tercih edilir IComparable yerine IComparable, değer türleri üzerinde boxing ve kutulama işlemleri önlemek için..net Framework sınıf kitaplığı koleksiyon sınıfları ile kullanılmak üzere birkaç genel arabirimleri tanımlar System.Collections.Generic ad.

Sınırlama türü parametresi olarak bir arabirim belirtildiğinde arabirimini uygulayan türleri kullanılabilir.Aşağıdaki kod örneği gösterildiği bir SortedList<T> türetildiği sınıfı GenericList<T> sınıfı.Daha fazla bilgi için bkz. Genel Türlere Giriş (C# Programlama Kılavuzu).SortedList<T>kısıtlamayı ekler where T : IComparable<T>.Böylece BubbleSort yönteminde SortedList<T> genel kullanmak için CompareTo liste öğeleri yöntemi.Bu örnekte, liste öğeleri basit bir sınıfı, Person, uygulayan, IComparable<Person>.

//Type parameter T in angle brackets. 
public class GenericList<T> : System.Collections.Generic.IEnumerable<T>
{
    protected Node head;
    protected Node current = null;

    // Nested class is also generic on T 
    protected class Node
    {
        public Node next;
        private T data;  //T as private member datatype 

        public Node(T t)  //T used in non-generic constructor
        {
            next = null;
            data = t;
        }

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

        public T Data  //T as return type of property
        {
            get { return data; }
            set { data = value; }
        }
    }

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

    public void AddHead(T t)  //T as method parameter type
    {
        Node n = new Node(t);
        n.Next = head;
        head = n;
    }

    // Implementation of the iterator 
    public System.Collections.Generic.IEnumerator<T> GetEnumerator()
    {
        Node current = head;
        while (current != null)
        {
            yield return current.Data;
            current = current.Next;
        }
    }

    // IEnumerable<T> inherits from IEnumerable, therefore this class  
    // must implement both the generic and non-generic versions of  
    // GetEnumerator. In most cases, the non-generic method can  
    // simply call the generic method.
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }
}

public class SortedList<T> : GenericList<T> where T : System.IComparable<T>
{
    // A simple, unoptimized sort algorithm that  
    // orders list elements from lowest to highest: 

    public void BubbleSort()
    {
        if (null == head || null == head.Next)
        {
            return;
        }
        bool swapped;

        do
        {
            Node previous = null;
            Node current = head;
            swapped = false;

            while (current.next != null)
            {
                //  Because we need to call this method, the SortedList 
                //  class is constrained on IEnumerable<T> 
                if (current.Data.CompareTo(current.next.Data) > 0)
                {
                    Node tmp = current.next;
                    current.next = current.next.next;
                    tmp.next = current;

                    if (previous == null)
                    {
                        head = tmp;
                    }
                    else
                    {
                        previous.next = tmp;
                    }
                    previous = tmp;
                    swapped = true;
                }
                else
                {
                    previous = current;
                    current = current.next;
                }
            }
        } while (swapped);
    }
}

// A simple class that implements IComparable<T> using itself as the  
// type argument. This is a common design pattern in objects that  
// are stored in generic lists. 
public class Person : System.IComparable<Person>
{
    string name;
    int age;

    public Person(string s, int i)
    {
        name = s;
        age = i;
    }

    // This will cause list elements to be sorted on age values. 
    public int CompareTo(Person p)
    {
        return age - p.age;
    }

    public override string ToString()
    {
        return name + ":" + age;
    }

    // Must implement Equals. 
    public bool Equals(Person p)
    {
        return (this.age == p.age);
    }
}

class Program
{
    static void Main()
    {
        //Declare and instantiate a new generic SortedList class. 
        //Person is the type argument.
        SortedList<Person> list = new SortedList<Person>();

        //Create name and age values to initialize Person objects. 
        string[] names = new string[] 
        { 
            "Franscoise", 
            "Bill", 
            "Li", 
            "Sandra", 
            "Gunnar", 
            "Alok", 
            "Hiroyuki", 
            "Maria", 
            "Alessandro", 
            "Raul" 
        };

        int[] ages = new int[] { 45, 19, 28, 23, 18, 9, 108, 72, 30, 35 };

        //Populate the list. 
        for (int x = 0; x < 10; x++)
        {
            list.AddHead(new Person(names[x], ages[x]));
        }

        //Print out unsorted list. 
        foreach (Person p in list)
        {
            System.Console.WriteLine(p.ToString());
        }
        System.Console.WriteLine("Done with unsorted list");

        //Sort the list.
        list.BubbleSort();

        //Print out sorted list. 
        foreach (Person p in list)
        {
            System.Console.WriteLine(p.ToString());
        }
        System.Console.WriteLine("Done with sorted list");
    }
}

Birden çok arabirimi olarak tek bir tür kısıtlamalar şu şekilde belirtilebilir:

class Stack<T> where T : System.IComparable<T>, IEnumerable<T>
{
}

Bir arabirim, birden fazla tür parametresi, aşağıdaki gibi tanımlayabilirsiniz:

interface IDictionary<K, V>
{
}

Sınıflar için geçerli olan kuralları devralma arabirimler için de geçerlidir:

interface IMonth<T> { }

interface IJanuary     : IMonth<int> { }  //No error 
interface IFebruary<T> : IMonth<int> { }  //No error 
interface IMarch<T>    : IMonth<T> { }    //No error 
//interface IApril<T>  : IMonth<T, U> {}  //Error

Genel arabirim yalnızca kendi tür parametresi bir dönüş değeri kullandığı anlamına contra-değişken ise generic arabirimlerden genel olmayan arabirimden devralabilir.İçinde.net Framework sınıf kitaplığı, IEnumerable devraldığı IEnumerable çünkü IEnumerable , yalnızca kullanır T dönüş değeri, GetEnumerator ve Current özellik Alıcısı.

Somut sınıf kapalı oluşturulmuş arabirimleri gibi uygulayabilirsiniz:

interface IBaseInterface<T> { }

class SampleClass : IBaseInterface<string> { }

Arabirimi tarafından aşağıdaki gibi gerekli tüm bağımsız değişkenler sınıf parametre listesi sağladığı sürece sýnýflarla generic arabirimlerden veya kapalı oluşturulmuş arabirim uygulayabilirsiniz:

interface IBaseInterface1<T> { }
interface IBaseInterface2<T, U> { }

class SampleClass1<T> : IBaseInterface1<T> { }          //No error 
class SampleClass2<T> : IBaseInterface2<T, string> { }  //No error

Yöntemi aşırı yüklenmesini denetleyen kurallar içinde genel sınıf, generic yapý ya da generic arabirimlerden yöntemleri için aynıdır.Daha fazla bilgi için bkz. Genel Yöntemler (C# Programlama Kılavuzu).

Ayrıca bkz.

Başvuru

Genel Türlere Giriş (C# Programlama Kılavuzu)

interface (C# Başvurusu)

Kavramlar

C# Programlama Kılavuzu

Diğer Kaynaklar

.NET Framework'te Genel Türler