Synopsis:
A C# Generic is a class that depends on one or more parameters that are not specified until an application uses it. Unlike
C++ templates, C# generics are created at run time1, and so, do not support specialization. You can, however,
define a constraint that supports using features of specific generic types.
Here is a demonstration Generic class that has a very typical structure, including a public string property, a property of the
generic type, and method for display.
The code below extends the previous demonstration by adding another generic parameter,
which requires a constraint. The second parameter is used to declare a
reference member which needs a default constructor. To compile, the code needs a constraint
promising that the type, U, has a default constructor.
Code in File GenericsDemo.cs
///////////////////////////////////////////////////////////////////// // GenericsDemo.cs - demonstrate basic generic class structure // // // // Jim Fawcett, CSE681 - Software Modeling and Analysis, Fall 2017 // ///////////////////////////////////////////////////////////////////// using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Generics { public class X<T> { public string name { get; set; } = "T container"; public T value { get; set; } public void say() { Console.Write( "\n my name is {0}\n I hold an instance of {1} with value {2}", name, typeof(T).Name, value.ToString() ); } } class TestX { static void Main(string[] args) { Console.Write("\n Demonstrate Simple Generic Class"); Console.Write("\n =================================="); Y y = new Y(); X<int> x1 = new X<int>(); x1.name = "x1"; x1.value = 3; x1.say(); X<double> x2 = new X<double>(); x2.name = "x2"; x2.value = 3.1415927; x2.say(); X<string> x3 = new X<string>(); x3.name = "x3"; x3.value = "aeiou"; x3.say(); Console.Write("\n\n"); } } }
Output
Demonstrate Simple Generic Class ================================== my name is x1 I hold an instance of Int32 with value 3 my name is x2 I hold an instance of Double with value 3.1415927 my name is x3 I hold an instance of String with value aeiou Press any key to continue . . .
Code in File GenericsDemoEx.cs
///////////////////////////////////////////////////////////////////// // GenericsDemoEx.cs - demonstrate basic generic class structure // // - extended, two generic parameters, one with constraint // // Jim Fawcett, CSE681 - Software Modeling and Analysis, Fall 2017 // ///////////////////////////////////////////////////////////////////// using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Generics { public class X<T, U> where U : new() // constraint { public string name { get; set; } = "T container"; public T value { get; set; } public void setU(U u) { u_ = u; } public void say() { Console.Write( "\n my name is {0}\n I hold an instance of {1} with value {2}", name, typeof(T).Name, value.ToString() ); if (u_ == null) return; Console.Write( "\n I also hold an instance of {0} with value {1}", typeof(U).Name, u_.ToString() ); } private U u_; // private member requiring default construction } public class Y { public override string ToString() { return "Y()"; } } class TestX { static void Main(string[] args) { Console.Write("\n Demonstrate Simple Generic Class"); Console.Write("\n =================================="); Y y = new Y(); X<int,Y> x1 = new X<int,Y>(); x1.name = "x1"; x1.value = 3; x1.setU(y); x1.say(); X<double,Y> x2 = new X<double,Y>(); x2.name = "x2"; x2.value = 3.1415927; x2.say(); X<string,Y> x3 = new X<string,Y>(); x3.name = "x3"; x3.value = "aeiou"; x3.say(); Console.Write("\n\n"); } } }
Output:
Demonstrate Simple Generic Class ================================== my name is x1 I hold an instance of Int32 with value 3 I also hold an instance of Y with value Y() my name is x2 I hold an instance of Double with value 3.1415927 my name is x3 I hold an instance of String with value aeiou Press any key to continue . . .
Example Code: