Le Tutoriel de C# Generics
1. La classe Generics
L'exemple ci-dessous définit une classe générique. KeyValue est une classe générique qui contient des paires de clés et de valeur (key/value).
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 dans la classe KeyValue<K,V> est appelé des paramètres génériques qui est un certain type de données. Lorsque vous utilisez cette classe, vous devez déterminer le paramètre spécifique.
Prennez l'exemple de l'utilisation la classe 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)
{
// Créez un objet KeyValue.
// int: Numéro de téléphone (K = int)
// string: Nom d'utilisateur. (V = string).
KeyValue<int, string> entry = new KeyValue<int, string>(12000111, "Tom");
// C# comprend que le type rendu est int (K = int).
int phone = entry.GetKey();
// C# comprend que le type rendu est string (V = string).
string name = entry.GetValue();
Console.WriteLine("Phone = " + phone + " / name = " + name);
Console.Read();
}
}
}
L'exécution de l'exemple:
Phone = 12000111 / name = Tom
2. La classe générique d'héritage
Une classe étendue à partir d'une classe générique peut spécifier un type de paramètre pour les génériques, conserver les paramètres génériques ou ajouter des paramètres génériques.
Exemple 1:
PhoneNameEntry.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
// Cette classe étend de la classe KeyValue<K,V>
// Et précise le type de deux paramètres K & V
// K = int (Numéro de téléphone).
// V = string (Nom d'utilisateur).
public class PhoneNameEntry : KeyValue<int, string>
{
public PhoneNameEntry(int key, string value)
: base(key, value)
{
}
}
}
L'exemple utilise PhoneNameEntry:
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# comprend que le type rendu est int.
int phone = entry.GetKey();
// C# comprend que le type rendu est string.
string name = entry.GetValue();
Console.WriteLine("Phone = " + phone + " / name = " + name);
Console.Read();
}
}
}
Exemple 2:
StringAndValueEntry.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
// Cette classe étend de la classe KeyValue<K,V>
// Spécifie le type du paramètre K est String.
// Garde le type du paramètre generic V.
public class StringAndValueEntry<V> : KeyValue<string, V>
{
public StringAndValueEntry(string key, V value)
: base(key, value)
{
}
}
}
L'exemple utilise la classe 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();
}
}
}
Exemple 3:
KeyValueInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
// Cette classe étend de la classe KeyValue<K,V>.
// Ella a ajouté un paramètre 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;
}
}
}
3. Generics Interface
Une Interface a le paramètre 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();
}
}
Par exemple: Une classe emt en oeuvre (implements) de l'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;
}
}
}
4. L'utilisation de Generic avec Exception
Vous pouvez créer une Exception avec des paramètres Generics.
MyException.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
class MyException<E> : ApplicationException
{
}
}
L'utilisation Generic Exception valide:
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)
{
// Fait quelque chose ici.
}
// Validé
catch (MyException<int> e)
{
// Fait quelque chose ici.
}
catch (Exception e)
{
}
}
}
}
L'utilisation de Generics Exception valide:
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)
{
// Fait quelque chose ici.
}
// Validé
catch (MyException<K> e)
{
// Fait quelque chose ici.
}
catch (Exception e)
{
}
}
}
}
L'utilisation Generics Exception invalide:
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)
{
// Fait quelque chose ici.
}
// Invalid (Unknown parameter K) ***********
// catch (MyException<K> e)
// {
// ...
// }
catch (Exception e)
{
}
}
}
}
5. Des méthodes generics
Une méthode en classe ou en Interface peut être générée (generify).
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;
}
}
}
Par exemple, l'utilisation la méthode 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);
// Une liste contenant le type d'élément KeyValue<int,string>.
List<KeyValue<int, string>> list = new List<KeyValue<int, string>>();
// Ajoutez des éléments à la liste.
list.Add(entry1);
list.Add(entry2);
KeyValue<int, string> firstEntry = MyUtils.GetFirstElement(list, null);
if (firstEntry != null)
{
Console.WriteLine("Value = " + firstEntry.GetValue());
}
Console.Read();
}
}
}
L'exécution de l'exemple:
Phone = 12000111
Value = Tom
6. L'initialisation des objets Generic
Parfois, vous souhaitez initialiser un objet Generic:
public void DoSomething<T>()
{
// Initialisation d'objet Generic
T t = new T(); // Error
}
La cause est que le paramètre T est peu probable qu'il ait le constructeur (constructor) T(), donc vous devez ajouter des contraintes when T : new(). Voyez l'exemple ci-dessous:
GenericInitializationExample.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace GenericsTutorial
{
class GenericInitializationExample
{
// Le type T doit avoir un Constructeur par défaut.
public void DoSomeThing<T>()
where T : new()
{
T t = new T();
}
// Le type K doit avoir un Constructeur par défaut
// et étend de la classe KeyValue.
public void ToDoSomeThing<K>()
where K: KeyValue<K,string>, new( )
{
K key = new K();
}
public T DoDefault<T>()
{
// Renvoie null si T est le type de référence (reference type).
// Hoặc 0 nếu T là kiểu số (int, float,..)
return default(T);
}
}
}
7. Le tableau Generic
Dans C# vous pouvez déclarer un tableau Generics:
// Initialisez un tableau.
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);
}
}
}
}
Tutoriels de programmation C#
- Héritage et polymorphisme en C#
- De quoi avez-vous besoin pour démarrer avec C#?
- Apprenez rapidement à développer en C# pour débutant
- Installer Visual Studio 2013 sur Windows
- Classe abstraite et interface dans C#
- Installer Visual Studio 2015 sur Windows
- Compression et décompression dans C#
- Tutoriel de programmation multithread C#
- Tutoriel C# Delegate et Event
- Installer AnkhSVN sur Windows
- Programmation C# pour l'équipe utilisant Visual Studio et SVN
- Installer .Net Framework
- Modificateur d'accès (Access Modifier) en C#
- Le Tutoriel de C# String et de StringBuilder
- Le Tutoriel de C# Properties
- Le Tutoriel de C# Enum
- Le Tutoriel de C# Structure
- Le Tutoriel de C# Generics
- Tutoriel sur la gestion des exceptions C#
- Le Tutoriel de C# Date Time
- Manipulation de fichiers et de répertoires dans C#
- Tutoriel C# Stream - flux binaire en C#
- Le Tutoriel d'expressions régulières C#
- Se Connecter à la base de données SQL Server dans C#
- Travailler avec la base de données SQL Server dans C#
- Connectez-vous à la base de données MySQL dans C#
- Travailler avec la base de données MySQL dans C#
- Connectez-vous à la base de données Oracle dans CSharp sans Oracle Client
- Utilisation d'une base de données Oracle en utilisant C#
Show More