Читайте также: |
|
Ниже приводится два примера использования типов struct для создания типов, которые могут использоваться аналогично встроенным типам языка, но имеют измененную семантику.
11.4.1 Тип целочисленного значения в базе данных
Представленная ниже структура DBInt реализует тип integer, который может представлять полный набор значений с типом int, а также дополнительное состояние, указывающее на неизвестное значение. Тип с такими характеристиками повсеместно используется в базах данных.
using System;
public struct DBInt
{
// The Null member represents an unknown DBInt value.
public static readonly DBInt Null = new DBInt();
// When the defined field is true, this DBInt represents a known value
// which is stored in the value field. When the defined field is false,
// this DBInt represents an unknown value, and the value field is 0.
int value;
bool defined;
// Private instance constructor. Creates a DBInt with a known value.
DBInt(int value) {
this.value = value;
this.defined = true;
}
// The IsNull property is true if this DBInt represents an unknown value.
public bool IsNull { get { return!defined; } }
// The Value property is the known value of this DBInt, or 0 if this
// DBInt represents an unknown value.
public int Value { get { return value; } }
// Implicit conversion from int to DBInt.
public static implicit operator DBInt(int x) {
return new DBInt(x);
}
// Explicit conversion from DBInt to int. Throws an exception if the
// given DBInt represents an unknown value.
public static explicit operator int(DBInt x) {
if (!x.defined) throw new InvalidOperationException();
return x.value;
}
public static DBInt operator +(DBInt x) {
return x;
}
public static DBInt operator -(DBInt x) {
return x.defined? -x.value: Null;
}
public static DBInt operator +(DBInt x, DBInt y) {
return x.defined && y.defined? x.value + y.value: Null;
}
public static DBInt operator -(DBInt x, DBInt y) {
return x.defined && y.defined? x.value - y.value: Null;
}
public static DBInt operator *(DBInt x, DBInt y) {
return x.defined && y.defined? x.value * y.value: Null;
}
public static DBInt operator /(DBInt x, DBInt y) {
return x.defined && y.defined? x.value / y.value: Null;
}
public static DBInt operator %(DBInt x, DBInt y) {
return x.defined && y.defined? x.value % y.value: Null;
}
public static DBBool operator ==(DBInt x, DBInt y) {
return x.defined && y.defined? x.value == y.value: DBBool.Null;
}
public static DBBool operator!=(DBInt x, DBInt y) {
return x.defined && y.defined? x.value!= y.value: DBBool.Null;
}
public static DBBool operator >(DBInt x, DBInt y) {
return x.defined && y.defined? x.value > y.value: DBBool.Null;
}
public static DBBool operator <(DBInt x, DBInt y) {
return x.defined && y.defined? x.value < y.value: DBBool.Null;
}
public static DBBool operator >=(DBInt x, DBInt y) {
return x.defined && y.defined? x.value >= y.value: DBBool.Null;
}
public static DBBool operator <=(DBInt x, DBInt y) {
return x.defined && y.defined? x.value <= y.value: DBBool.Null;
}
public override bool Equals(object obj) {
if (!(obj is DBInt)) return false;
DBInt x = (DBInt)obj;
return value == x.value && defined == x.defined;
}
public override int GetHashCode() {
return value;
}
public override string ToString() {
return defined? value.ToString(): “DBInt.Null”;
}
}
11.4.2 Логический тип базы данных
Представленная ниже структура DBBool реализует трехзначный логический тип. Возможными значениями этого типа являются значения DBBool.True, DBBool.False и DBBool.Null, где член Null указывает неизвестное значение. Подобные трехзначные логические типы часто используются в базах данных.
using System;
public struct DBBool
{
// The three possible DBBool values.
public static readonly DBBool Null = new DBBool(0);
public static readonly DBBool False = new DBBool(-1);
public static readonly DBBool True = new DBBool(1);
// Private field that stores –1, 0, 1 for False, Null, True.
sbyte value;
// Private instance constructor. The value parameter must be –1, 0, or 1.
DBBool(int value) {
this.value = (sbyte)value;
}
// Properties to examine the value of a DBBool. Return true if this
// DBBool has the given value, false otherwise.
public bool IsNull { get { return value == 0; } }
public bool IsFalse { get { return value < 0; } }
public bool IsTrue { get { return value > 0; } }
// Implicit conversion from bool to DBBool. Maps true to DBBool.True and
// false to DBBool.False.
public static implicit operator DBBool(bool x) {
return x? True: False;
}
// Explicit conversion from DBBool to bool. Throws an exception if the
// given DBBool is Null, otherwise returns true or false.
public static explicit operator bool(DBBool x) {
if (x.value == 0) throw new InvalidOperationException();
return x.value > 0;
}
// Equality operator. Returns Null if either operand is Null, otherwise
// returns True or False.
public static DBBool operator ==(DBBool x, DBBool y) {
if (x.value == 0 || y.value == 0) return Null;
return x.value == y.value? True: False;
}
// Inequality operator. Returns Null if either operand is Null, otherwise
// returns True or False.
public static DBBool operator!=(DBBool x, DBBool y) {
if (x.value == 0 || y.value == 0) return Null;
return x.value!= y.value? True: False;
}
// Logical negation operator. Returns True if the operand is False, Null
// if the operand is Null, or False if the operand is True.
public static DBBool operator!(DBBool x) {
return new DBBool(-x.value);
}
// Logical AND operator. Returns False if either operand is False,
// otherwise Null if either operand is Null, otherwise True.
public static DBBool operator &(DBBool x, DBBool y) {
return new DBBool(x.value < y.value? x.value: y.value);
}
// Logical OR operator. Returns True if either operand is True, otherwise
// Null if either operand is Null, otherwise False.
public static DBBool operator |(DBBool x, DBBool y) {
return new DBBool(x.value > y.value? x.value: y.value);
}
// Definitely true operator. Returns true if the operand is True, false
// otherwise.
public static bool operator true(DBBool x) {
return x.value > 0;
}
// Definitely false operator. Returns true if the operand is False, false
// otherwise.
public static bool operator false(DBBool x) {
return x.value < 0;
}
public override bool Equals(object obj) {
if (!(obj is DBBool)) return false;
return value == ((DBBool)obj).value;
}
public override int GetHashCode() {
return value;
}
public override string ToString() {
if (value > 0) return "DBBool.True";
if (value < 0) return "DBBool.False";
return "DBBool.Null";
}
}
12. Массивы
Массив представляет собой структуру данных, содержащую ряд переменных, доступ к которым осуществляется с использованием расчетных индексов. Все переменные, содержащиеся в массиве, которые также называются элементами массива, имеют одинаковый тип, который называется типом элементов массива.
Массив имеет ранг, определяющий количество индексов, связанных с каждым из элементов массива. Другими словами, ранг массива указывает количество его измерений. Массив с рангом, равным единице, называется одномерным массивом. Массив с рангом больше единицы называется многомерным массивом. Многомерные массивы конкретного размера часто называются двумерными, трехмерными и так далее.
Каждое измерение массива имеет сопоставленную ему длину, выраженную в виде целого неотрицательного числа. Длины измерений не являются частью типа массива, они устанавливаются при создании экземпляра массива с конкретным типом во время выполнения. Длина измерения определяет допустимый диапазон индексов для этого измерения: для измерения с длиной N индексы могут находиться в диапазоне от 0 до N – 1 включительно. Общее количество элементов в массиве равно произведению длин всех его размерностей. Если одно или несколько измерений массива имеют нулевую длину, массив считается пустым.
Элемент массива может иметь любой тип, в том числе тип массива.
12.1 Типы массива
Тип массива записывается как тип_не_массива, за которым следуют спецификации_ранга:
тип_массива:
тип_не_массива спецификации_ранга
тип_не_массива:
тип
спецификации_ранга:
спецификация_ранга
спецификации_ранга спецификация_ранга
спецификация_ранга:
[ разделители_размерностейнеобязательно ]
разделители_размерностей:
,
разделители_размерностей,
Тип_не_массива является одним из типов, которые сами по себе не являются типом_массива.
Ранг типа массива задается левой спецификацией_ранга в типе_массива: спецификация_ранга указывает, что массив имеет ранг, равный единице плюс число меток «,» в этой спецификации.
Тип элемента массива представляет собой тип, полученный в результате удаления крайней левой спецификации_ранга:
· Тип массива в форме T[R] указывает массив с рангом R и типом элемента (типом_не_массива) T.
· Тип массива в форме T[R][R1]...[RN] указывает массив с рангом R и типом элемента T[R1]...[RN].
В результате данные спецификации_ранга считываются слева направо перед последним типом элемента (типом_не_массива). Тип int[][,,][,] указывает одномерный массив трехмерных массивов из двумерных массивов значений с типом int.
Во время выполнения значение типа массива может быть равно null или может содержать ссылку на экземпляр массива этого типа.
System.Array
Тип System.Array является абстрактным базовым типом для всех типов массива. Выполняется неявное преобразование ссылок (§6.1.6) из любого типа в тип System.Array, а также явное преобразование ссылок (§6.2.4) из типа System.Array в любой тип массива. Обратите внимание, что тип System.Array сам по себе не является типом_массива. Это тип_класса, на основе которого создаются все типы_массива.
Во время выполнения значение с типом System.Array может быть равным null или содержать ссылку на экземпляр с любым типом массива.
IList
В одномерном массиве T[] реализуется интерфейс System.Collections.Generic.IList<T> (сокращенно IList<T>) и его базовые интерфейсы. В связи с этим выполняется неявное преобразование из T[] в IList<T> и его базовые интерфейсы. В дополнение к этому при наличии неявного преобразования ссылок из S в T в массиве S[] реализуется интерфейс IList<T> и выполняется неявное преобразование ссылок из S[] в IList<T> и его базовые интерфейсы (§6.1.6). При наличии явного преобразования ссылок из S в T выполняется явное преобразование ссылок из S[] в IList<T> и его базовые интерфейсы (§6.2.4). Пример:
Дата добавления: 2015-11-14; просмотров: 57 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
GetEnumerator 1 страница | | | GetEnumerator 13 страница |