Die Anleitung zu C# Generics

1- Generic Class, Interface

1.1- Die Klasse Generics

Das folgende Beispiel definiert eine Klasse generics. KeyValue ist eine Klasse generics, die ein Paar Schlüssel und Wert (key/value) enthaltet.
 
KeyValue.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{
   public class KeyValue<K, V>
   {

       private K key;
       private V value;

       public KeyValue(K key, V value)
       {
           this.key = key;
           this.value = value;
       }

       public K GetKey()
       {
           return key;
       }

       public void SetKey(K key)
       {
           this.key = key;
       }

       public V GetValue()
       {
           return value;
       }

       public void SetValue(V value)
       {
           this.value = value;
       }

   }

}
K, V in die Klasse  KeyValue<K,V> werden als der Parameter generics genannt. Es ist ein Typ von Daten. Bei der Benutzung der Klasse sollen Sie den bestimmten Parameter festlegen
Sehen Sie bitte die Beispiel der Benutzung von der Klasse   KeyValue.
KeyValueDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{
    public class KeyValueDemo
    {

        public static void Main(string[] args)
        {
            // Create KeyValue object.
            // int: Phone Number (K = int)
            // string: Name (V = string)
            KeyValue<int, string> entry = new KeyValue<int, string>(12000111, "Tom");

            // C# understands that the return type is a int
            int phone = entry.GetKey();

            // C# understands that the return type is a string
            string name = entry.GetValue();

            Console.WriteLine("Phone = " + phone + " / name = " + name);

            Console.Read();
        }

    }

}
Das Beispiel durchführen

1.2- Die Erbe von der Klasse Generics

Eine Klasse, die  verlängert aus einer Klasse, kann das Typ für den Parameter generics festlegen, die generics Parameter halten oder die generics Parameter einfügen

Das Beispiel 1:

PhoneNameEntry.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{

    // This class extends KeyValue<K,V>
    // And specify the type for the K & V
    // K = int (Phone Number)
    // V = string (Name)
    public class PhoneNameEntry : KeyValue<int, string>
    {

        public PhoneNameEntry(int key, string value)
            : base(key, value)
        {

        }

    }

}
Zum Beispiel: PhoneNameEntry benutzen:
PhoneNameEntryDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{
    public class PhoneNameEntryDemo
    {

        public static void Main(string[] args)
        {

            PhoneNameEntry entry = new PhoneNameEntry(12000111, "Tom");

            // C# understands that the return type is int.
            int phone = entry.GetKey();

            // C# understands that the return type is string.
            string name = entry.GetValue();

            Console.WriteLine("Phone = " + phone + " / name = " + name);

            Console.Read();

        }

    }

}

Das Beispiel 2

StringAndValueEntry.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{

    // This class extends KeyValue<K,V>
    // Specify the parameter K is string.
    public class StringAndValueEntry<V> : KeyValue<string, V>
    {

        public StringAndValueEntry(string key, V value)
            : base(key, value)
        {
        }

    }

}
Das Beispiel für die Benutzung der Klasse StringAndValueEntry:
StringAndValueEntryDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{
    public class StringAndValueEntryDemo
    {

        public static void main(String[] args)
        {

            // (Emp Number, Employee Name)
            // V = string (Employee Name)
            StringAndValueEntry<String> entry = new StringAndValueEntry<String>("E001", "Tom");

            String empNumber = entry.GetKey();

            String empName = entry.GetValue();

            Console.WriteLine("Emp Number = " + empNumber);
            Console.WriteLine("Emp Name = " + empName);

            Console.Read();

        }
    }

}

Zum Beispiel 3:

KeyValueInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{

    // This class extends KeyValue<K,V>.
    // It has added a parameter generics I.
    public class KeyValueInfo<K, V, I> : KeyValue<K, V>
    {

        private I info;

        public KeyValueInfo(K key, V value)
            : base(key, value)
        {
        }

        public KeyValueInfo(K key, V value, I info)
            : base(key, value)
        {
            this.info = info;
        }

        public I GetInfo()
        {
            return info;
        }

        public void GetInfo(I info)
        {
            this.info = info;
        }

    }

}

1.3- Generics Interface

Eine Interface mit dem Parameter Generics:
GenericInterface.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{
  public interface GenericInterface<G>
  {

      G DoSomething();

  }

}
Zum Beispiel: eine Klasse zur Durchführung der Interface:
GenericInterfaceImpl.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{

   public class GenericInterfaceImpl<G> : GenericInterface<G>
   {

       private G something;

       public G DoSomething()
       {
           return something;
       }

   }

}

1.4- Die Benutzung von Generic mit Exception

Sie können eine Exception mit den Parameter Generics definieren
MyException.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{
   class MyException<E> : ApplicationException
   {

   }

}
Generic Exception gültig benutzen:
UsingGenericExceptionValid01.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{
    class UsingGenericExceptionValid01
    {

        public void SomeMethod()
        {
            try
            {
                // ...
            }
            // Valid
            catch (MyException<string> e)
            {
                // Do something here.
            }
            // Valid
            catch (MyException<int> e)
            {
                // Do something here.
            }
            catch (Exception e)
            {
            }
        }

    }

}
Die gültige Benutzung von Generics Exception 
UsingGenericExceptionValid02.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{
    class UsingGenericExceptionValid02<K>
    {
        public void SomeMethod()
        {
            try
            {
                // ...
            }
            // Valid
            catch (MyException<string> e)
            {
                // Do something here.
            }
            // Valid
            catch (MyException<K> e)
            {
                // Do something here.
            }
            catch (Exception e)
            {
            }
        }
    }

}
Generics Exception nicht gültig benutzen
UsingGenericExceptionInvalid.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{
    class UsingGenericExceptionInvalid
    {
        public void SomeMethod()
        {
            try
            {
                // ...
            }
            // Valid
            catch (MyException<string> e)
            {
                // Do something here.
            } 
            // Invalid (Unknown parameter K) *********** 
            // catch (MyException<K> e)
            // {
                // ...            
            // }
            catch (Exception e)
            {
            }
        }
    }

}

2- Die Methode generics

Eine Methode in die Klasse oder Interface kann generified werden 
MyUtils.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{
    public class MyUtils
    {
        // <K, V>: To say that this method has two parameters K, V
        // Method returns K.
        public static K GetKey<K, V>(KeyValue<K, V> entry)
        {
            K key = entry.GetKey();
            return key;
        }

        // <K, V>: To say that this method has two parameters K, V
        // Method returns V.
        public static V GetValue<K, V>(KeyValue<K, V> entry)
        {
            V value = entry.GetValue();
            return value;
        }

        // List <E>: The list contains the elements of type E
        // This method returns the type E.    
        public static E GetFirstElement<E>(List<E> list, E defaultValue)
        {
            if (list == null || list.Count == 0)
            {
                return defaultValue;
            }
            E first = list.ElementAt(0);
            return first;
        }

    }

}
Zum Beispiel: die Benutzung von der Methode generics:
MyUtilsDemo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{
    public class MyUtilsDemo
    {

        public static void Main(string[] args)
        {

            // K = int: Phone
            // V = string: Name
            KeyValue<int, string> entry1 = new KeyValue<int, String>(12000111, "Tom");
            KeyValue<int, string> entry2 = new KeyValue<int, String>(12000112, "Jerry");

            // (K = int).
            int phone = MyUtils.GetKey(entry1);
            Console.WriteLine("Phone = " + phone);

            // A list containing the element type KeyValue<int, string>.
            List<KeyValue<int, string>> list = new List<KeyValue<int, string>>();

            // Add element to list
            list.Add(entry1);
            list.Add(entry2);

            KeyValue<int, string> firstEntry = MyUtils.GetFirstElement(list, null);

            if (firstEntry != null)
            {
                Console.WriteLine("Value = " + firstEntry.GetValue());
            }

            Console.Read();
        }

    }

}
Das Beispiel durchführen

3- Die Initialisierung des Objekt Generic

Manchmal möchten Sie ein Objekt Generic initialisieren:
public void DoSomething<T>()
{

     // Generic Object Initialization
     T t = new T(); // Error

}
Der Grund: der T parameter ist nicht sicher, den Constructor T() zu haben . Deshalb sollen Sie   when T : new() einfügen. Sehen Sie das folgende Beispiel
GenericInitializationExample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{
    class GenericInitializationExample 
    {
        // Type T must have default constructor.
        public void DoSomeThing<T>()
            where T : new()
        {
            T t = new T();
        }

        // Type K must have default constructor.
        // and extends KeyValue<K,string>
        public void ToDoSomeThing<K>()
            where K: KeyValue<K,string>, new( )
        {
            K key = new K();
        }


        public T DoDefault<T>()
        {
            // Return null if T is reference type
            // or return 0 if T is number (int, float,..) 
            return default(T);
        }
    }

}

4- Array Generic

Im  C# können Sie ein Array  Generics melden:
// Initialize an array.
T[] myArray = new T[10];
GenericArrayExample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GenericsTutorial
{
   class GenericArrayExample
   {

       public static T[] FilledArray<T>(T value, int count)
       {
           T[] ret = new T[count];
           for (int i = 0; i < count; i++)
           {
               ret[i] = value;
           }
           return ret;
       }

       public static void Main(string[] args)
       {

           string value = "Hello";

           string[] filledArray = FilledArray<string>(value, 10);

           foreach (string s in filledArray)
           {
               Console.WriteLine(s);
           }
       }
   }

}

View more categories: