Generics and arrays - type specific operations
Generics and arrays - type specific operations
Tuesday, 01 March 2011
Article Index
Generics and arrays - type specific operations



Along with the generic versions of Sort, other useful generic methods were introduced along with generics including Find, FindAll, FindIndex, FindLast and FindLastIndex, LastIndexOf, TrueForAll, ConvertAll.

Once you have seen how the Find method works the rest are easy to understand. The Find method returns the array element that satisfies a condition, it is defined as:    

public static T Find<T> ( 
T[] array,
      Predicate<T> match

The Predicate delegate function is defined as:

public delegate bool Predicate<T> (
      T obj

From these you can probably work out how to use Find correctly.

For example, to pick out the first negative value in the array we first need a suitable predicate with the correct generic signature:

public bool MyLess(int x)
return (x < 0);

Notice that this implies that T is int.


Now we can return the first negative value in the array using:

int result=Array.Find(A, MyLess);

If having to introduce an explicit method, e.g. MyLess, is something you would rather avoid then you could use an anonymous delegate:

int result = Array.Find(A,
delegate(int x) { return (x < 0); });

The same thing works for all of the generic methods.

For example:

Array.Sort(A, delegate(int x, int y)
{return (((int)y).CompareTo((int)x)); });

Notice that there are some generic methods that need you to specify the types because the compiler cannot work them out from the context.

For example, the very useful ConvertAll can be used to implement custom conversion from one array type to another. To convert from Int32 to Int64 you would write:

public Int64 MyConvert(Int32 input)
return (Int64)input;

So far nothing new, but to call the ConvertAll method you need to write:

Int64[] B = Array.ConvertAll<Int32, Int64>(
A, MyConvert);

You can’t drop the <Int32,Int64> type definition because it’s just too difficult for the compiler to work out.

To generalize the pattern

In summary, the generic methods make working with arrays and collections in general much easier because they allow you to pass in generic methods which perform type specific operations - compare, fid convert and so on.

You can use this approach in general situations where you need to implement a generic algorithm but with type specific methods. Simply pass in the type specific operation as a generic delegate and provide a concrete implementation of the method when you call the generic method.  For example, if you need to write a generic method that adds generic types you would pass in a generic Add delegate that provided the type specific implementation.

For example, the generic method would be something like:

public MyGenericMethod<T> (
 T a, T b,     
Addmethod<T> add )
T c=add(a,b);

Notice that the add method is a type dependent operation.

To make this work the Addmethod generic delegate would be something like:


public delegate T Addmethod<T> (T x,T y)


And following this you could define an Addmethod for integers as:

int Adder(int x,int y)
return x+y;

and you could call the generic method customised for integers as:

public MyGenericMethod<int> (a,b,Adder)

It is something of a chore to have to package the type specific operation in a delegate each time you want to use the generic method but lambda expressions make it less painful.



Deep C# - Anonymous Methods, Lambdas And Closures

Anonymous methods aren't particularly new, but they have hidden depths and lead on to lambdas and the idea of a closure. These are all important ideas in modern programming.

Multicast Delegates and Events

Multicast delegates are useful in their own right but they also form the basis on which the C# event system is built. We take a close look at how they work and how to use them. For example, did you kn [ ... ]

Other Articles






Last Updated ( Tuesday, 01 March 2011 )

RSS feed of all content
I Programmer - full contents
Copyright © 2018 All Rights Reserved.
Joomla! is Free Software released under the GNU/GPL License.