Полное руководство. С# 4.0
Шрифт:
Объект, проверяемый по заданному условию, передается в качестве параметра obj. Если объект obj удовлетворяет заданному условию, то предикат должен возвра тить логическое значение true, в противном случае — логическое значение false. Предикаты используются в ряде методов класса Array, включая: Exists, Find, FindIndex и FindAll.
В приведенном ниже примере программы демонстрируется применение предика та с целью определить, содержится ли в целочисленном массиве отрицательное зна чение. Если такое значение обнаруживается, то данная программа извлекает первое отрицательное значение, найденное в массиве. Для этого в ней используются методы Exists и Find. // Продемонстрировать применение предикатного делегата. using System; class PredDemo { // Предикатный метод, возвращающий логическое значение true, // если значение переменной v оказывается отрицательным. static bool IsNeg(int v) { if(v < 0) return true; return false; } static void Main { int[] nums = { 1, 4, -1, 5, -9 }; Console.Write("Содержимое массива nums: "); foreach(int i in nums) Console.Write(i + " "); Console.WriteLine; // Сначала проверить, содержит ли массив nums
Эта программа дает следующий результат. Содержимое массива nums: 1 4 -1 5 -9 Массив nums содержит отрицательное значение. Первое отрицательное значение: -1
В данном примере программы в качестве предиката методам Exists и Find передается метод IsNeg. Обратите внимание на следующее объявление метода IsNeg. static bool IsNeg(int v) {
Методы Exists и Find автоматически и по порядку передают элементы мас сива переменной v. Следовательно, после каждого вызова метода IsNeg переменная v будет содержать следующий элемент массива. Применение делегата Action
Делегат Action применяется в методе Array.ForEach для выполнения заданного действия над каждым элементом массива. Существуют разные формы делегата Action, отличающиеся числом параметров типа. Ниже приведена одна из таких форм. public delegate void Action<T> (T obj)
В этой форме объект, над которым должно выполняться действие, передается в ка честве параметра obj. Когда же эта форма делегата Action применяется в методе Array.ForEach, то каждый элемент массива передается по порядку объекту obj. Следовательно, используя делегат Action и метод ForEach, можно в одном опера торе выполнить заданную операцию над целым массивом.
В приведенном ниже примере программы демонстрируется применение делегата Action и метода ForEach. Сначала в ней создается массив объектов класса MyClass, а затем используется метод Show для отображения значений, извлекаемых из этого массива. Далее эти значения становятся отрицательными с помощью метода Neg. И наконец, метод Show используется еще раз для отображения отрицательных зна чений. Все эти операции выполняются посредством вызовов метода ForEach. // Продемонстрировать применение делегата Action. using System; class MyClass { public int i; public MyClass(int x) { i = x; } } class ActionDemo { // Метод делегата Action, отображающий значение, которое ему передается. static void Show(MyClass о) { Console.Write(о.i + " "); } // Еще один метод делегата Action, делающий // отрицательным значение, которое ему передается. static void Neg(MyClass о) { o.i = -o.i; } static void Main { MyClass[] nums = new MyClass[5]; nums[0] = new MyClass(5); nums[1] = new MyClass(2); nums[2] = new MyClass(3), nums[3] = new MyClass(4); nums[4] = new MyClass(1); Console.Write("Содержимое массива nums: "); // Выполнить действие для отображения значений. Array.ForEach(nums, ActionDemo.Show); Console.WriteLine; // Выполнить действие для отрицания значений. Array.ForEach(nums, ActionDemo.Neg); Console.Write("Содержимое массива nums после отрицания: "); // Выполнить действие для повторного отображения значений. Array.ForEach(nums, ActionDemo.Show); Console.WriteLine; } }
Ниже приведен результат выполнения этой программы. Содержимое массива nums: 5 2 3 4 1 Содержимое массива nums после отрицания: -5 -2 -3 -4 -1 Класс BitConverter
В программировании нередко требуется преобразовать встроенный тип данных в массив байтов. Допустим, что на некоторое устройство требуется отправить целое значение, но сделать это нужно отдельными байтами, передаваемыми по очереди. Часто возникает и обратная ситуация, когда данные получаются из устройства в виде упорядоченной последовательности байтов, которые требуется преобразовать в один из встроенных типов. Для подобных преобразований в среде .NET предусмотрен от дельный класс BitConverter.
Класс BitConverter является статическим. Он содержит методы, приведенные в табл. 21.13. Кроме того, в нем определено следующее поле. public static readonly bool IsLittleEndian
Это поле принимает логическое значение true, если в текущей среде сначала со храняется младший байт слова, а затем старший. Это так называемый формат с пря мым порядком байтов. А если в текущей среде сначала сохраняется старший байт слова, а затем младший, то поле IsLittleEndian принимает логическое значение false. Это так называемый формат с обратным порядком байтов. В компьютерах с процессором Intel Pentium используется формат с прямым порядком байтов.
Таблица 21.13. Методы, определенные в классе BitConverter Метод Назначение public static long DoubleToInt64Bits(double value) Преобразует значение value в целочисленное значение типа long и возвращает результат public static byte[] GetBytes(bool value) Преобразует значение value в однобайтовый массив и возвращает результат public static byte[] GetBytes(char value) Преобразует значение value в двухбайтовый массив и возвращает результат public static byte[] GetBytes(double value) Преобразует значение value в восьмибайтовый массив и возвращает результат public static byte[] GetBytes(float value) Преобразует значение value в четырехбайтовый массив и возвращает результат public static byte[] GetBytes(int value) Преобразует значение value в четырехбайтовый массив и возвращает результат public static byte[] GetBytes(long value) Преобразует значение value в восьмибайтовый массив и возвращает результат public static byte[] GetBytes(short value) Преобразует значение value в двухбайтовый массив и возвращает результат public static byte[] GetBytes(uint value) Преобразует значение value в четырехбайтовый массив и возвращает результат public static byte[] GetBytes(ulong value) Преобразует значение value в восьмибайтовый массив и возвращает результат public static byte[] GetBytes(ushort value) Преобразует значение value в двухбайтовый массив и возвращает результат public static double Int64BitsToDouble(long value) Преобразует значение value в значение типа double и возвращает результат public static bool ToBoolean(byte[] value, int startIndex) Преобразует байт из элемента массива, указываемого по индексу value[startIndex], в эквивалентное значение типа bool и возвращает результат. Ненулевое значение преобразуется в логическое значение true, а нулевое — в логическое значение false public static char ToChar(byte[] value, int index) Преобразует два байта, начиная с элемента массива value[index], в эквивалентное значение типа char и возвращает результат public static double ToDouble(byte[] value, int startIndex) Преобразует восемь байтов, начиная с элемента массива value[startIndex], в эквивалентное значение типа double и возвращает результат public static short ToInt16(byte[] value, int startIndex) Преобразует два байта, начиная с элемента массива value[startIndex], в эквивалентное значение типа short и возвращает результат public static int ToInt32(byte[] value, int startIndex) Преобразует четыре байта, начиная с элемента массива value[startIndex], в эквивалентное значение типа int и возвращает результат public static long ToInt64(byte[] value, int startIndex) Преобразует восемь байтов, начиная с элемента массива value[startIndex], в эквивалентное значение типа long и возвращает результат public static float ToSingle(byte[] value, int startIndex) Преобразует четыре байта, начиная с элемента массива value[startIndex], в эквивалентное значение типа float и возвращает результат public static string ToString(byte[] value) Преобразует байты из массива value в символьную строку. Строка содержит шестнадцатеричные значения, связанные с этими байтами и разделенные дефисами public static string ToString(byte[] value, int startIndex) Преобразует байты из массива value в символьную строку, начиная с элемента value[startIndex]. Строка содержит шестнадцатеричные значения, связанные с этими байтами и разделенные дефисами public static string ToString(byte[] value, int startIndex, int length) Преобразует байты из массива value в символьную строку, начиная с элемента value[startIndex] и включая число элементов, определяемых параметром length. Строка содержит шестнадцатеричные значения, связанные с этими байтами и разделенные дефисами public static ushort ToUInt16(byte[] value, int startIndex) Преобразует два байта, начиная с элемента массива value[startIndex], в эквивалентное значение типа ushort и возвращает результат public static uint ToUInt32(byte[] value, int startIndex) Преобразует четыре байта, начиная с элемента массива value[startIndex], в эквивалентное значение типа uint и возвращает результат public static ulong ToUInt64(byte[] value, int startIndex) Преобразует восемь байтов, начиная с элемента массива value[startIndex], в эквивалентное значение типа ulong и возвращает результат Генерирование случайных чисел средствами класса Random
Для генерирования последовательного ряда случайных чисел служит класс Random. Такие последовательности чисел оказываются полезными в самых разных ситуациях, включая имитационное моделирование. Начало последовательности случайных чисел определяется некоторым начальным числом, которое может задаваться автоматически или указываться явным образом.
В классе Random определяются два конструктора. public Random public Random(int seed)
Первый конструктор создает объект типа Random, использующий системное время для определения начального числа. А во втором конструкторе используется начальное значение seed, задаваемое явным образом.
Методы, определенные в классе Random, перечислены в табл. 21.14.
Таблица 21.14. Методы, определенные в классе Random Метод Назначение public virtual int Next Возвращает следующее случайное целое число, которое будет находиться в пределах от 0 до Int32. MaxValue-1 включительно public virtual int Next(int maxValue) Возвращает следующее случайное целое число, которое будет находиться в пределах от 0 до maxValue-1 включительно public virtual int Next(int minValue, int maxValue) Возвращает следующее случайное целое число, которое будет находиться в пределах от minValue до maxValue-1 включительно public virtual void NextBytes(byte[] buffer) Заполняет массив buffer последовательностью случайных целых чисел. Каждый байт в массиве будет находиться в пределах от 0 до Byte.MaxValue-1 включительно public virtual double NextDouble Возвращает из последовательности следующее случайное число, которое представлено в форме с плавающей точкой, больше или равно 0,0 и меньше 1,0 protected virtual double Sample Возвращает из последовательности следующее случайное число, которое представлено в форме с плавающей точкой, больше или равно 0,0 и меньше 1,0. Для получения несимметричного или специального распределения случайных чисел этот метод необходимо переопределить в производном классе
Ниже приведена программа, в которой применение класса Random демонстрирует ся на примере создания компьютерного варианта пары игральных костей. // Компьютерный вариант пары игральных костей. using System; class RandDice { static void Main { Random ran = new Random; Console.Write(ran.Next(1, 7) + " "); Console.WriteLine(ran.Next(1, 7)); } }
При выполнении этой программы три раза подряд могут быть подучены, напри мер, следующие результаты. 5 2 4 4 1 6
Сначала в этой программе создается объект класса Random. А затем в ней запраши ваются два случайных значения в пределах от 1 до 6. Управление памятью и класс GC