Home Random Page


CATEGORIES:

BiologyChemistryConstructionCultureEcologyEconomyElectronicsFinanceGeographyHistoryInformaticsLawMathematicsMechanicsMedicineOtherPedagogyPhilosophyPhysicsPolicyPsychologySociologySportTourism






Nbsp;   Casting Arrays

For arrays with reference type elements, the CLR allows you to implicitly cast the source array’s ele- ment type to a target type. For the cast to succeed, both array types must have the same number of dimensions, and an implicit or explicit conversion from the source element type to the target ele- ment type must exist. The CLR doesn’t allow the casting of arrays with value type elements to any other type. (However, by using the Array.Copy method, you can create a new array and populate its elements in order to obtain the desired effect.) The following code demonstrates how array casting works.

 

// Create a two­dimensional FileStream array. FileStream[,] fs2dim = new FileStream[5, 10];

 

// Implicit cast to a two­dimensional Object array Object[,] o2dim = fs2dim;

 

// Can't cast from two­dimensional array to one­dimensional array

// Compiler error CS0030: Cannot convert type 'object[*,*]' to

// 'System.IO.Stream[]'

Stream[] s1dim = (Stream[]) o2dim;

 

// Explicit cast to two­dimensional Stream array Stream[,] s2dim = (Stream[,]) o2dim;

 

// Explicit cast to two­dimensional String array

// Compiles but throws InvalidCastException at runtime String[,] st2dim = (String[,]) o2dim;

 

// Create a one­dimensional Int32 array (value types). Int32[] i1dim = new Int32[5];

 

// Can't cast from array of value types to anything else

// Compiler error CS0030: Cannot convert type 'int[]' to 'object[]' Object[] o1dim = (Object[]) i1dim;

 

// Create a new array, then use Array.Copy to coerce each element in the

// source array to the desired type in the destination array.

// The following code creates an array of references to boxed Int32s. Object[] ob1dim = new Object[i1dim.Length];

Array.Copy(i1dim, ob1dim, i1dim.Length);

 

The Array.Copy method is not just a method that copies elements from one array to another. The Copy method handles overlapping regions of memory correctly, as does C’s memmove function. C’s memcpy function, on the other hand, doesn’t handle overlapping regions correctly. The Copy method can also convert each array element as it is copied if conversion is required. The Copy method is ca- pable of performing the following conversions:

■ Boxing value type elements to reference type elements, such as copying an Int32[] to an

Object[].

 

■ Unboxing reference type elements to value type elements, such as copying an Object[] to an Int32[].


■ Widening CLR primitive value types, such as copying elements from an Int32[] to a

Double[].

 

■ Downcasting elements when copying between array types that can’t be proven to be compatible based on the array’s type, such as when casting from an Object[] to an IFormattable[]. If every object in the Object[] implements IFormattable, Copy will succeed.

Here’s another example showing the usefulness of Copy.

 

// Define a value type that implements an interface. internal struct MyValueType : IComparable {



public Int32 CompareTo(Object obj) {

...

}

}

 

 

public static class Program { public static void Main() {

// Create an array of 100 value types. MyValueType[] src = new MyValueType[100];

 

// Create an array of IComparable references. IComparable[] dest = new IComparable[src.Length];

 

// Initialize an array of IComparable elements to refer to boxed

// versions of elements in the source array. Array.Copy(src, dest, src.Length);

}

}

 

As you might imagine, the Framework Class Library (FCL) takes advantage of Array’s Copy method quite frequently.

In some situations, it is useful to cast an array from one type to another. This kind of functionality is called array covariance. When you take advantage of array covariance, you should be aware of an associated performance penalty. Let’s say you have the following code.

 

String[] sa = new String[100];

Object[] oa = sa; // oa refers to an array of String elements

oa[5] = "Jeff"; // Perf hit: CLR checks oa's element type for String; OK oa[3] = 5; // Perf hit: CLR checks oa's element type for Int32; throws

// ArrayTypeMismatchException

 

In the preceding code, the oa variable is typed as an Object[]; however, it really refers to a String[]. The compiler will allow you to write code that attempts to put a 5 into an array element because 5 is an Int32, which is derived from Object. Of course, the CLR must ensure type safety, and when assigning to an array element, the CLR must ensure that the assignment is legal. So the CLR must check at run time whether the array contains Int32 elements. In this case, it doesn’t, and the assignment cannot be allowed; the CLR will throw an ArrayTypeMismatchException.


 

 

 
 

All Arrays Are Implicitly Derived from System.Array

When you declare an array variable like this:

 

FileStream[] fsArray;

 

then the CLR automatically creates a FileStream[] type for the AppDomain. This type will be im- plicitly derived from the System.Array type, and therefore, all of the instance methods and proper- ties defined on the System.Array type will be inherited by the FileStream[] type, allowing these methods and properties to be called using the fsArray variable. This makes working with arrays extremely convenient because there are many helpful instance methods and properties defined by System.Array, such as Clone, CopyTo, GetLength, GetLongLength, GetLowerBound, GetUpper­ Bound, Length, Rank, and others.

The System.Array type also exposes a large number of extremely useful static methods that operate on arrays. These methods all take a reference to an array as a parameter. Some of the useful static methods are AsReadOnly, BinarySearch, Clear, ConstrainedCopy, ConvertAll, Copy, Exists, Find, FindAll, FindIndex, FindLast, FindLastIndex, ForEach, IndexOf, LastIndexOf, Resize, Reverse, Sort, and TrueForAll. There are many overloads for each of these methods. In fact, many of the methods provide generic overloads for compile-time type safety as well as good performance. I encourage you to examine the SDK documentation to get an understanding of how useful and powerful these methods are.



Date: 2016-03-03; view: 681


<== previous page | next page ==>
Nbsp;   Initializing Array Elements | Nbsp;   All Arrays Implicitly Implement IEnumerable, ICollection, and IList
doclecture.net - lectures - 2014-2024 year. Copyright infringement or personal data (0.006 sec.)