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: