C# Collections: Introduction to Generics
Generic Methods
|
Introduction
|
|
Imagine you want to pass different types of values to
various methods of a class to primarily accomplish the same purpose. You may
be tempted to overloaded a method in various versions as follows:
|
using System; public class Generator { // Display the value of an integer public void Show(int value) { Console.WriteLine(value); } // Display the value of a double-precesion value public void Show(double value) { Console.WriteLine(value); } // Display the value of a character public void Show(char value) { Console.WriteLine(value); } }
public class Exercise { static int Main() { var exo = new Generator(); // Call the version of the method that displays an integer exo.Show(246); // Call the version of the method that displays a character exo.Show('G'); // Call the version of the method that displays a decimal exo.Show(355.65); return 0; } }
This would produce:
246 G 355.65 Press any key to continue . . .
We passed a constant value directly to the method when
we called it. Remember that you can also first declare a variable, assign it
a value, and then pass that variable to the method. Here are examples:
public class Exercise { static int Main() { var exo = new Generator(); // Call the version of the method that displays an integer var Value1 = 246; exo.Show(Value1); // Call the version of the method that displays a character var Value2 = 'G'; exo.Show(Value2); // Call the version of the method that displays a decimal var Value3 = 355.65; exo.Show(Value3); return 0; } }
Although this is based on the concept of method
overloading, another way you can solve this type of problem is to create one
method that "doesn't know" the type of value that would be passed to it but
the method is equipped to process the value somehow. Based on the above
program, you can create one method that takes an argument and it displays
its value. To do this, at the time you are defining the method, you only let
it know that it would receive an argument but you don't specify the type of
value that it will process. Such a method is referred to as generic.
- Start Microsoft Visual Studio and create a new Console Application named CommercialStore1
- To create a new class, on the main menu, click Project -> Add Class...
- Set the Name to StoreItem and press Enter
- Change the file as follows:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CommercialStore1 { public class StoreItem { public class CItem { public double Item; public CItem Next; } public CItem Head = null; public int Size; public int Count() { return Size; } public int Add(CItem NewItem) { CItem Sample = new CItem(); Sample = NewItem; Sample.Next = Head; Head = Sample; return Size++; } public CItem Retrieve(int Position) { CItem Current = Head; for (int i = Count() - 1; i > Position && Current != null; i--) { Current = Current.Next; } return Current; } public void ShowItem(double item) { Console.WriteLine("Item: {0}", item); } } }
- Access the Program.cs file and change it as follows:
using System; namespace CommercialStore1 { public class Program { static void Main() { StoreItem exo = new StoreItem(); StoreItem.CItem Part; Part = new StoreItem.CItem(); Part.Item = 97.43; exo.Add(Part); Part = new StoreItem.CItem(); Part.Item = 274.87; exo.Add(Part); Part = new StoreItem.CItem(); Part.Item = 8.7873; exo.Add(Part); Part = new StoreItem.CItem(); Part.Item = 2764.4; exo.Add(Part); Part = new StoreItem.CItem(); Part.Item = 92.4662; exo.Add(Part); Part = new StoreItem.CItem(); Part.Item = 66800.85; exo.Add(Part); Console.WriteLine("-=- List of Items -=-"); for (int i = 0; i < exo.Count(); i++) { StoreItem.CItem One = exo.Retrieve(i); exo.ShowItem(One.Item); } Console.WriteLine("\nNumber of Items: {0}\n", exo.Count()); } } }
- Execute the application to see the result
-=- List of Items -=- Item: 97.43 Item: 274.87 Item: 8.7873 Item: 2764.4 Item: 92.4662 Item: 66800.9 Number of Items: 6 Press any key to continue . . .
- Close the DOS window
A generic method is a method that can process a value
whose type is known only when the variable is accessed. To create a generic
method, on the right side of the name of the method, type the <> operator.
Inside of the <> operator, enter a letter or a name, which is referred to as
parameter type. Here is an example:
public class Generator
{
public void Show<TypeOfValue>()
{
}
}
One of the ways you can use the parameter type is to
pass an argument to the method. You do this by preceding the name of the
argument with the parameter type. Here is an example:
public class Generator
{
public void Show<TypeOfValue>(TypeOfValue value)
{
}
}
In the body of the method, you can process the argument
as you see fit. At a minimum, and based on our earlier program, you can
simply display the value by passing it to the Console.WriteLine()
method. Here is an example:
public class Generator
{
public void Show<TypeOfValue>(TypeOfValue value)
{
Console.WriteLine(value);
}
}
By tradition, most programmers and most documents use
the letter T for the parameter type.
Application:
Creating a Generic Method
|
- To create a generic method, change the ShowItem() method as follows:
public void ShowItem<T>(T item) { Console.WriteLine("Item: {0}", item); }
Calling a Generic Method
|
As mentioned earlier, one of the particularities of a
generic method is that, at the time it is defined, the method doesn't know
the type of the parameter. This means that, when calling the method, you
must make sure you clearly specify the type of value that will be processed.
You can do this by directly passing (a constant of) the type of value that
the method will process. Here are different examples of calling our Show()
method:
using System; public class Generator { public void Show<T>(T value) { Console.WriteLine(value); } } public class Exercise { static int Main() { var exo = new Generator(); // Call the version of the method that displays an integer var Value1 = 246; exo.Show(Value1); // Call the version of the method that displays a character var Value2 = 'G'; exo.Show(Value2); // Call the version of the method that displays a decimal var Value3 = 355.65; exo.Show(Value3); return 0; } }
When complied and executed, this program would produce:
246 G 355.65 Press any key to continue . . .
As an alternative, you can type the name of the method,
followed by angle brackets. Inside of the brackets, enter the data type of
the value that will be processed. After the angle brackets, open the
parentheses and, inside of them, type the constant value that will be
processed. Here are examples:
using System; public class Generator { public void Show<T>(T value) { Console.WriteLine(value); } } public class Program { static int Main() { var exo = new Generator(); // Call the version of the method that displays an integer var Value1 = 246; exo.Show<int>(Value1); // Call the version of the method that displays a character var Value2 = 'G'; exo.Show<char>(Value2); // Call the version of the method that displays a decimal var Value3 = 355.65; exo.Show<double>(Value3); return 0; } }
You can also declare the value as a constant before
passing it to the method.
Application:
Calling a Generic Method
|
- To specify the parameter type of a generic method when calling it,
change the Main() method as follows:
class Program { static void Main() { . . . Console.WriteLine("-=- List of Items -=-"); for (int i = 0; i < exo.Count(); i++) { Exercise.CItem One = exo.Retrieve(i); exo.ShowItem<double>(One.Item); } Console.WriteLine("\nNumber of Items: {0}\n", exo.Count()); } }
- Execute the application and notice that it works fine
- Close the DOS window
A Generic Method With Various Parameters
|
Introduction
|
Just like a method can take one argument, it can take
various generic parameters. You can pass one parameter as a known type and
the other as a generic type. Here is an example:
using System; public class Generator { public void Show<T>(string msg, T value) { Console.WriteLine("{0}: {1}", msg, value); } } public class Exercise { static int Main() { var exo = new Generator(); exo.Show<int>("Integer", 246); exo.Show<char>("Character", 'G'); exo.Show<double>("Decimal", 355.65); return 0; } }
This would produce:
Integer: 246 Character: G Decimal: 355.65 Press any key to continue . . .
Although we directly passed the values to the method
when calling it, you can first declare a variable before passing it to the
method. Here are examples:
using System; public class Generator { public void Show<TypeOfValue>(string msg, TypeOfValue value) { Console.WriteLine("{0}: {1}", msg, value); } } public class Exercise { static int Main() { var exo = new Generator(); var message = "Integer"; const int iValue = 246; exo.Show<int>(message, iValue); message = "Character"; const char cValue = 'G'; exo.Show<char>(message, cValue); message = "Decimal"; const double dValue = 355.65; exo.Show<double>(message, dValue); return 0; } }
Application:
Using a Method With Various Parameters
|
- Access the StoreItem.cs file
- To create and use a method with various parameters, make the
following changes:
namespace CommercialStore1 { public class StoreItem { . . . public void ShowItem<T>(string content, int index, T item) { Console.WriteLine("{0} {1}: {2}", content, index, item); } } }
- Access the Program.cs file and change it as follows:
namespace CommercialStore1 { class Program { static void Main() { . . . for (int i = 0; i < exo.Count(); i++) { Exercise.CItem One = exo.Retrieve(i); exo.ShowItem<double>("Item", i+1, One.Item); } Console.WriteLine("\nNumber of Items: {0}\n", exo.Count()); } } }
- Execute the application
-=- List of Items -=- Item 1: 97.43 Item 2: 274.87 Item 3: 8.7873 Item 4: 2764.4 Item 5: 92.4662 Item 6: 66800.85 Number of Items: 6 Press any key to continue . . .
- Close the DOS window
A Generic Method With Various Parameter Types
|
As seen above, you can pass different arguments to a
method. You can also pass different parameter types, in any appropriate
order of your choice, to a method. To pass two parameter types to a method,
inside its <> operator, enter the names of two parameter types separated by
a comma. Here is an example:
public class Generator
{
public void Show<FirstType, SecondType>()
{
}
}
If you want to use the parameter types, you can pass an
argument for each to the method. Remember that each parameter type
represents a data type; so you can use it as the type of an argument. Here
are examples:
public class Generator
{
public void Show<FirstType, SecondType>(FirstType first,
SecondType second)
{
}
}
In the body of the method, you can then use the
arguments as you see fit. For example, you can display their values by
passing them to the Console.WriteLine() method. Here is an example:
public class Generator
{
public void Show<FirstType, SecondType>(FirstType first,
SecondType second)
{
Console.WriteLine("First: {0}\nSecond: {1}\n", first, second);
}
}
Calling a Generic Method With Various Parameter
Types
|
To call a method that takes various parameters, you can
simply pass it the value of each argument. Here is an example:
using System;
public class Generator
{
public void Show<FirstType, SecondType>(FirstType first,
SecondType second)
{
Console.WriteLine("First: {0}\nSecond: {1}\n", first, second);
}
}
public class Exercise
{
static int Main()
{
var exo = new Generator();
var iValue = 246;
var message = "Some Message";
exo.Show(message, iValue);
return 0;
}
}
This would produce:
First: Some Message Second: 246 Press any key to continue . . .
An alternative is to specify the type of each argument.
To do this, inside the <> operator on the right side of the name of the
method, enter the data types separated by a comma. Here are examples:
using System; public class Generator { public void Show<FirstType, SecondType>(FirstType first, SecondType second) { Console.WriteLine("First: {0}\nSecond: {1}\n", first, second); } } public class Exercise { static int Main() { var exo = new Generator(); var iValue = 246; var message = "Some Message"; exo.Show(message, iValue); iValue = 85; var cValue = 'G'; exo.Show<int, char>(iValue, cValue); var weeklyHours = 42.50d; var hourlySalary = 25.05; exo.Show<double, double>(weeklyHours, hourlySalary); return 0; } }
This would produce:
First: Some Message Second: 246 First: 85 Second: G First: 42.5 Second: 25.05 Press any key to continue . . .
Notice that the arguments can be of the same type or
different types. It is up to you to determine the type of a particular
argument when calling the method.
Generic Methods and Optional Arguments
|
In our introduction, we saw that when you create a
generic method, you indicate that it takes an argument but you don't know or
don't specify the type of that argument. We also saw that you can pass more
than one argument to the method. One of the arguments can be a parameter
type while the other is a known type. Here is an example we used:
using System;
public class Generator
{
public void Show<T>(string msg, T value)
{
Console.WriteLine("{0}: {1}", msg, value);
}
}
public class Exercise
{
static int Main()
{
var exo = new Generator();
exo.Show<int>("Integer", 246);
exo.Show<char>("Character", 'G');
exo.Show<double>("Decimal", 355.65);
return 0;
}
}
If you want to assign default values to arguments, only
the known data types can receive optional arguments. There is no default
value for the parameter type because its type is not known. Consider the
following method:
public class Generator { public void Show<T>(string msg = "Number", T value = null) { Console.WriteLine("{0}: {1}", msg, value); } }
This would produce the following error:
Error 1 A value of type '<null>' cannot be used as a default parameter because there are no standard conversions to type 'T' C:\Users\Administrator\AppData\Local\Temporary Projects\exo1\Exercise.cs 5 58 GenericInheritance
As a result, if you are creating a method that takes
more than one argument and you want to use default values, the parameter
type(s) must come first and the one (those) with optional value(s) value(s)
must come last. The parameter type(s) must not have default value(s).
Consider the following program:
using System; public class Generator { public void Show<T>(T value, string msg = "Number") { Console.WriteLine("{0}: {1}", msg, value); } } public class Exercise { static int Main() { var exo = new Generator(); exo.Show<int>(246); exo.Show<char>('G', "Character"); exo.Show<double>(355.65); return 0; } }
This would produce:
Number: 246 Character: G Number: 355.65 Press any key to continue . . .
Generic Methods and Named Arguments
|
When calling a method that takes one or more arguments,
when calling it, you can use the name of an argument followed by a colon and
followed by the desired value. This is also valid for parameter types. Here
are examples:
using System; public class Generator { public void Evaluate<T>(T right, T left, char operation) { Console.WriteLine("{0}{1}{2}", left, operation, right); } } public class Exercise { static int Main() { var exo = new Generator(); var a = 20.64; var b = 797.24; exo.Evaluate<double>(a, b, '+'); var r = "Research "; var d = " Development"; var oper = '&'; exo.Evaluate<string>(operation : oper, right : d, left : r); exo.Evaluate<int>(right : 14159, left : 31, operation : '.'); return 0; } }
This would produce:
797.24+20.64 Research & Development 31.14159 Press any key to continue . . .
Generic Classes
|
Introduction
|
Like a method, a class can be created as a generic. When
a class is created as generic, it is asked to process a value wihtout
knowing what type that value is. This means that the class will know the
type of value only when it is called.
To create a generic class, on the right side of the name
of the class, type the <> operator and enter a name for the parameter type.
Here is an example:
public class Exercise<TypeOfValue>
{
}
This parameter type is just a representative of a data
type. As a data type, you can use it to declare a variable in the body of
the class. Here is an example:
public class Exercise<TypeOfValue>
{
public TypeOfValue value;
}
After declaring such a variable, you can use it in your
application. For example, you can access it outside of the class using the
period operator. Inside of the class, one way you can use the variable is to
display its value using one of the methods of the class. Here is an example:
public class Exercise<TypeOfValue>
{
public TypeOfValue value;
public void Show()
{
Console.WriteLine("Value: {0}\n", value);
}
}
Application:
Introducing Generic Classes
|
- To start a new program, on the main menu, click the File -> New Project ...
- Click Console Application. Set the Name to CommercialStore2 and press Enter
- To create a new class, on the main menu, click Project -> Add Class...
- Set the Name to ListOfItems and click OK
- Change the file as follows:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CommercialStore2 { public class ListOfItems { public class CItem { public double Item; public CItem Next; } public ListOfItems() { Head = null; Size = 0; } public CItem Head; public int Size; public int Count() { return Size; } public int Add(CItem NewItem) { CItem Sample = new CItem(); Sample = NewItem; Sample.Next = Head; Head = Sample; return Size++; } public CItem Retrieve(int Position) { CItem Current = Head; for (int i = Count() - 1; i > Position && Current != null; i--) { Current = Current.Next; } return Current; } } }
- Access the Program.cs file and change it as follows:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CommercialStore2 { public class Program { static void Main() { ListOfItems exo = new ListOfItems(); ListOfItems.CItem Part; Part = new ListOfItems.CItem(); Part.Item = 97.43; exo.Add(Part); Part = new ListOfItems.CItem(); Part.Item = 274.87; exo.Add(Part); Part = new ListOfItems.CItem(); Part.Item = 8.7873; exo.Add(Part); Part = new ListOfItems.CItem(); Part.Item = 2764.4; exo.Add(Part); Part = new ListOfItems.CItem(); Part.Item = 92.4662; exo.Add(Part); Part = new ListOfItems.CItem(); Part.Item = 66800.85; exo.Add(Part); Console.WriteLine("-=- List of Items -=-"); for (int i = 0; i < exo.Count(); i++) { ListOfItems.CItem One = exo.Retrieve(i); Console.WriteLine("Item: {0}", One.Item); } Console.WriteLine("\nNumber of Items: {0}\n", exo.Count()); } } }
- Execute the application and test it:
-=- List of Items -=- Item: 97.43 Item: 274.87 Item: 8.7873 Item: 2764.4 Item: 92.4662 Item: 66800.85 Number of Items: 6 Press any key to continue . . .
- Close the DOS window
Using a Generic Class
|
After creating a generic class, you can use it. One way
to do this, as we have learned in previous lessons, consists of declaring a
variable for it. In previous lessons, to declare a variable of a class, we
would write:
Exercise exo = new Exercise();
If the class is generic, on the right side of its name
when declaring the variable, type the <> operator. Inside of this operator,
enter the data type that will be processed as the parameter type of the
generic class. Here is an example:
using System; public class Generator<TypeOfValue> { public TypeOfValue value; public void Show() { Console.WriteLine("Value: {0}\n", value); } } public class Exercise { static int Main() { Generator<int> exo = new Generator<int>(); return 0; } }
You can also declare a variable of a generic type using
the var keyword. To do this, use var on
the left side of the variable name, omit the <> operator and the data type.
This would be done as follows:
public class Exercise
{
static int Main()
{
var exo = new Generator<int>();
return 0;
}
}
After declaring the variable (whether using the name of
the class or the var keyword), you can then access the member(s) of
the class using the period operator. Here are examples:
using System; public class Generator<TypeOfValue> { public TypeOfValue value; public void Show() { Console.WriteLine("Value: {0}\n", value); } } public class Exercise { static int Main() { var exo = new Generator<int>(); var iValue = 246; exo.value = iValue; exo.Show(); return 0; } }
Passing a Parameter Type to a Method
|
We saw that you could declare a variable of a parameter
type in the generic class. Another way you can use it is to pass it as an
argument to a method and make the argument a parameter type. As seen
previously, you can use the argument as you see fit. For example, you can
display its value to the console. Here is an example:
using System; public class Generator<TypeOfValue> { public void Show(TypeOfValue value) { Console.WriteLine("Value: {0}\n", value); } } public class Exercise { static int Main() { var exo = new Generator<int>(); var iValue = 246; exo.Show(iValue); return 0; } }
In the same way, you can pass the parameter type to a
constructor of the class. Here is an example:
public class Generator<TypeOfValue> { private TypeOfValue val; public Exercise(TypeOfValue v) { val = v; } }
Returning a Parameter Type
|
Besides, or as opposed to, passing a parameter type, you
can create a method that returns a parameter type. Once again, you can
primarily observe the rules we reviewed for returning a value from a method.
Here is an example:
using System;
public class Generator<TypeOfValue>
{
private TypeOfValue val;
public Generator(TypeOfValue v)
{
val = v;
}
public TypeOfValue GetValue()
{
return val;
}
}
public class Exercise
{
static int Main()
{
var exo = new Generator<double>(35.65);
Console.WriteLine("Value: {0}\n", exo.GetValue());
return 0;
}
}
Application:
Returning a Parameter Type
|
- Open the ListOfItems.cs source file
- To apply what we have reviewed, change the file as follows:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CommercialStore2 { public class ListOfItems { public class CItem<T> { public double Item; public CItem<T> Next; } public ListOfItems() { Head = null; Size = 0; } public CItem<double> Head; public int Size; public int Count() { return Size; } public int Add(CItem<double> NewItem) { CItem<double> Sample = new CItem<double>(); Sample = NewItem; Sample.Next = Head; Head = Sample; return Size++; } public CItem<double> Retrieve(int Position) { CItem<double> Current = Head; for (int i = Count() - 1; i > Position && Current != null; i--) { Current = Current.Next; } return Current; } } }
- Access the Program file and change it as follows:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace CommercialStore2 { public class Program { static void Main() { ListOfItems exo = new ListOfItems(); ListOfItems.CItem<double> Part; Part = new ListOfItems.CItem<double>(); Part.Item = 97.43; exo.Add(Part); Part = new ListOfItems.CItem<double>(); Part.Item = 274.87; exo.Add(Part); Part = new ListOfItems.CItem<double>(); Part.Item = 8.7873; exo.Add(Part); Part = new ListOfItems.CItem<double>(); Part.Item = 2764.4; exo.Add(Part); Part = new ListOfItems.CItem<double>(); Part.Item = 92.4662; exo.Add(Part); Part = new ListOfItems.CItem<double>(); Part.Item = 66800.85; exo.Add(Part); Console.WriteLine("-=- List of Items -=-"); for (int i = 0; i < exo.Count(); i++) { ListOfItems.CItem<double> One = exo.Retrieve(i); Console.WriteLine("Item: {0}", One.Item); } Console.WriteLine("\nNumber of Items: {0}\n", exo.Count()); } } }
- Execute the application and test it
- Close the DOS window
A Property of the Parameter Type
|
You can create a property that is of the parameter type
of the generic class. There is no significant rule to follow when creating
the property, except that you should remember that, at the time you are
creating the property, the class doesn't know the type of the parameter.
Here is an example:
using System;
public class Generator<TypeOfValue>
{
private TypeOfValue val;
public TypeOfValue Value
{
get { return val; }
set { val = value; }
}
public void Show()
{
Console.WriteLine("Value: {0}\n", val);
}
}
public class Exercise
{
static int Main()
{
var exo = new Generator<int>();
exo.Value = 246;
exo.Show();
return 0;
}
}
A Generic Class With Multiple Parameters
|
Using Multiple Type Parameters
|
As done for generic methods, when creating a generic
class, you can specify more than one parameter type. To do this, in the <>
operator, after the first generic type, enter a comma and another generic
type. Here is an example:
public class Generator<FirstType, SecondType>
{
}
If you know for sure that the parameters will be of the
same type, you can use one method to process both. Otherwise, you can
declare the necessary members for each type. You can also create a method
that would take many arguments with each argument of a particular type. Here
are examples:
using System;
public class Generator<FirstType, SecondType>
{
private FirstType t;
private SecondType v;
public void SetTValue(FirstType value)
{
t = value;
}
public FirstType GetTValue()
{
return t;
}
public void SetVValue(SecondType value)
{
v = value;
}
public V GetVValue()
{
return v;
}
public void Show(FirstType tValue, SecondType vValue)
{
Console.WriteLine("First: {0}\nSecond: {1}", tValue, vValue);
}
}
When declaring a variable for the class, make sure you
appropriately specify the list of parameter types. Here are two examples:
public class Exercise { static int Main() { Generator<int, int> IntTypes = new Generator<int, int>(); IntTypes.SetTValue(246); IntTypes.SetVValue(6088); IntTypes.Show(IntTypes.GetTValue(), IntTypes.GetVValue()); Generator<double, double> DoubleTypes = new Generator<double, double>(); DoubleTypes.SetTValue(355.65); DoubleTypes.SetVValue(1785.426); DoubleTypes.Show(DoubleTypes.GetTValue(), DoubleTypes.GetVValue()); Generator<short, decimal> Disparate = new Generator<short, decimal>(); DoubleTypes.SetTValue(42); DoubleTypes.SetVValue(245580.35); DoubleTypes.Show(DoubleTypes.GetTValue(), DoubleTypes.GetVValue()); return 0; } }
You can also declare the variable using the var
keyword. To do this, on the left side of the assignment operator, type only
the var keyword and the name of the operator. Here is an
example:
public class Exercise { static int Main() { var IntTypes = new Generator<int, int>(); IntTypes.SetTValue(246); IntTypes.SetVValue(6088); IntTypes.Show(IntTypes.GetTValue(), IntTypes.GetVValue()); var DoubleTypes = new Generator<double, double>(); DoubleTypes.SetTValue(355.65); DoubleTypes.SetVValue(1785.426); DoubleTypes.Show(DoubleTypes.GetTValue(), DoubleTypes.GetVValue()); var Disparate = new Generator<short, decimal>(); DoubleTypes.SetTValue(42); DoubleTypes.SetVValue(245580.35); DoubleTypes.Show(DoubleTypes.GetTValue(), DoubleTypes.GetVValue()); return 0; } }
This would produce:
First: 246 Second: 6088 First: 355.65 Second: 1785.426 First: 42 Second: 245580.35 Press any key to continue . . .
If a generic class has more than one parameter type,
they don't have to be of the same type. At the time you are creating the
class, you may not specify their types but you can anticipate that they
would be different. It is when you declare the variable that you would need
to determine their precise types.
Even if the parameters are of primitive types, you can
first declare the variables and pass them to the class.
A Class as a Parameter Type
|
So far, in our examples, we treated the parameter type
as a primitive data type. A parameter type can also be a formal class,
either one that you created yourself or one that exists as part of the C#
language. When creating the generic class, you must follow all the rules we
have reviewed so far for generic classess. Here is such a simple class:
public class Generator { public void Show(TypeOfValue val) { Console.WriteLine("{0}\n", val.ToString()); } }
As mentioned already, the class that would be processed
by the generic one must have been previously created so it can be used as a
parameter. When declaring a variable of the generic class, make sure you
enter the name of the normal class in place of the parameter type.
Everything else is as we have done so far. Here is an example:
using System; public class FourSideGeometricFigure { private string nm; private double bs; private double hg; public string Name { get { return nm; } set { nm = value; } } public double Base { get { return bs; } set { bs = value; } } public double Height { get { return hg; } set { hg = value; } } public double Area { get { return bs * hg; } } public override string ToString() { string result = "Type: " + nm + "\n" + "Base: " + bs.ToString() + "\n" + "Height: " + hg.ToString() + "\n" + "Area: " + Area.ToString(); return result; } } public class Generator<TypeOfValue> { public void Show(TypeOfValue val) { Console.WriteLine("{0}\n", val.ToString()); } } public class Exercise { static int Main() { var sqr = new FourSideGeometricFigure(); sqr.Name = "Square"; sqr.Base = 36.82; sqr.Height = 36.82; Generator<FourSideGeometricFigure> exoSquare = new Generator<FourSideGeometricFigure>(); exoSquare.Show(sqr); FourSideGeometricFigure rect = new FourSideGeometricFigure(); rect.Name = "Rectangle"; rect.Base = 52.94; rect.Height = 27.58; Generator<FourSideGeometricFigure> exoRect = new Generator<FourSideGeometricFigure>(); exoRect.Show(rect); return 0; } }
You can also declare the variable using the var keyword.
Here are examples:
public class Exercise { static int Main() { var sqr = new FourSideGeometricFigure(); sqr.Name = "Square"; sqr.Base = 36.82; sqr.Height = 36.82; var exoSquare = new Generator<FourSideGeometricFigure>(); exoSquare.Show(sqr); FourSideGeometricFigure rect = new FourSideGeometricFigure(); rect.Name = "Rectangle"; rect.Base = 52.94; rect.Height = 27.58; var exoRect = new Generator<FourSideGeometricFigure>(); exoRect.Show(rect); return 0; } }
This would produce:
Type: Square Base: 36.82 Height: 36.82 Area: 1355.7124 Type: Rectangle Base: 52.94 Height: 27.58 Area: 1460.0852 Press any key to continue . . .
In the same way, you can create a generic class that
takes more than one parameter.
No comments :
Post a Comment