Generics can also be applied to structs. For example, suppose that you have a Coordinate struct defined as follows:

public struct Coordinate {

 public int x, y, z;

}

The coordinates for the Coordinate struct takes in int values. You can use generics on the Coordinate struct, like this:

public struct Coordinate<T> {

 public T x, y, z;

}

To use int values for the Coordinate struct, you can do so via the following statements:

Coordinate<int> pt1;

pt1.x = 5;

pt1.y = 6;

pt1.z = 7;

To use float values for the Coordinate struct, utilize the following statements:

Coordinate<float> pt2;

pt2.x = 2.0F;

pt2.y = 6.3F;

pt2.z = 2.9F;

Generic Methods

In addition to generic classes and interfaces, you can also define generic methods. Consider the following class definition and the method contained within it:

public class SomeClass {

 public void DoSomething<T>(T t) {}

}

Here, DoSomething() is a generic method. To use a generic method, you need to provide the type when calling it:

SomeClass sc = new SomeClass();

sc.DoSomething<int>(3);

The C# compiler, however, is smart enough to deduce the type based on the argument passed into the method, so the following statement automatically infers T to be of type String:

sc.DoSomething('This is a string'); //---T is String---

This feature is known as generic type inference.

You can also define a constraint for the generic type in a method, like this:

public class SomeClass {

 public void DoSomething<T>(T t) where T : IComparable<T> {

 }

}

If you need the generic type to be applicable to the entire class, define the type T at the class level:

public class SomeClass<T> where T : IComparable<T> {

 public void DoSomething(T t) { }

}

In this case, you specify the type during the instantiation of SomeClass:

SomeClass<int> sc = new SomeClass<int>();

sc.DoSomething(3);

You can also use generics on static methods, in addition to instance methods as just described. For example, the earlier DoSomething() method can be modified to become a static method:

public class SomeClass {

 public static void DoSomething<T>(T t)

  where T : IComparable<T> {}

}

To call this static generic method, you can either explicitly specify the type or use generic type inference:

SomeClass.DoSomething(3);

//---or---

SomeClass.DoSomething<int>(3);

Generic Operators

Generics can also be applied to operators. Consider the generic MyStack class discussed earlier in this chapter. Suppose that you want to be able to join two MyStack objects together, like this:

MyStack<string> stack1 = new MyStack<string>(4);

stack1.Push('A');

stack1.Push('B');

MyStack<string> stack2 = new MyStack<string>(2);

stack2.Push('C');

stack2.Push('D');

stack1 += stack2;

In this case, you can overload the + operator, as highlighted in the following code:

public class MyStack<T> where T : IComparable<T> {

 private T[] _elements;

 private int _pointer;

 public MyStack(int size) {

  _elements = new T[size];

  _pointer = 0;

 }

 public void Push(T item) {

  if (_pointer < _elements.Length - 1) {

   throw new Exception('Stack is full.');

  }

  _elements[_pointer] = item;

  _pointer++;

 }

 public T Pop() {

Вы читаете C# 2008 Programmer's Reference
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату