Опубликован: 25.03.2010 | Доступ: свободный | Студентов: 1447 / 157 | Оценка: 4.31 / 4.00 | Длительность: 25:42:00
Лекция 20:

Консольные приложения в С#

< Лекция 19 || Лекция 20: 1234567891011

Статические методы класса System.Object

Мы испробовали работу метода Equals() в двух вариантах:

  1. в базовом варианте он сравнивает ссылки двух объектов одинакового типа и возвращает true, если ссылки имеют одинаковое значение, что означает, что обе ссылки указывают на один и тот же объект
  2. в перегруженном варианте мы заставили его производить поэлементное сравнение значений составляющих объект членов-данных

Но разработчики класса System.Object предусмотрели для обоих этих целей специално два статических метода

  1. System.Object.Equals() - сравнивает значения составляющих-членов двух объектов
  2. System.Object.ReferenceEquals() - сравнивает значения ссылок на два объекта

Испытаем эти методы, изменив соответствующим образом код предыдущего примера. При этом следует помнить, что эти два метода статические. Это значит, что они существуют применительно к классу, а не к конкретному объекту. И вызывать их нужно с использованием имени класса. И еще напомним, что для класса Object простанства имен System определен псевдоним object как стандартный (встроенный) тип языка C#.

И так, листинг примера...

using System;
  
namespace Test
{
//**********************************************************************
// Класс, хранящий информацию о человеке
//**********************************************************************
class Person
{
//******************************************
// Закрытые (private) данные о человеке
//******************************************
string Name;// ФИО
string Inn; // Номер налогоплательщика
int Age;    // Возраст
  
//******************************************
// Конструкторы
//******************************************
public Person(){} // Пустой конструктор по умолчанию

//******************************************
public Person(string name, string inn, int age)
{
  Name = name;
  Inn = inn;
  Age = age;
}
}
  
//**********************************************************************
// Клиент Main()
// Точка входа в приложение
//**********************************************************************
class App
{
static void Main()
  {
  // Создаем два объекта с одинаковыми состояниями
  Person person1 = new Person("Sally", 
    "2222-33-5555", 21);
  Person person2 = new Person("Sally", 
    "2222-33-5555", 21);
  string p1 = "Привет всем!";
  string p2 = "Привет всем!";
  // Сравниваем внутреннее состояние двух объектов
  Console.WriteLine("Содержимое двух объектов 
    одинаково? - {0}", object.Equals(p1, p2));
        
  // Сравниваем значения ссылок
  Console.WriteLine("Занимают они одну память? - {0}",
    object.ReferenceEquals(person1, person2));
      
  while(true);
  }
}
}
Листинг 20.20 . Демонстрация статических методов класса System.Object

Результаты экрана

Содержимое двух объектов одинаково? - True 
Занимают они одну память? - False

Системные типы данных и их псевдонимы как встроенные типы C#

Любой встроенный в C# тип данных - это лишь псевдоним для существующего типа, определенного в пространстве имен System. В таблице приведены все системные типы данных и соответствующие им псевдонимы C#, а также информация о совместимости с общей средой выполнения CLR (Common Language Runtime). Совместимость обеспечивается правилами, установленными CLS (Common Language Specification).

Таблица 20.5 . Системные типы данных и их псевдонимы в C#
Псевдоним C# Соответствие CLS Системный тип Диапазон Пояснения
void + Void Пусто Применяется для соблюдения синтаксиса
sbyte - SByte -128 —127 Знаковое 8 бит
byte + Byte 0 —255 Беззнаковое 8 бит
short + Int16 -32'768 —32'767 Знаковое 16 бит
ushort - UInt16 0 —65'535 Беззнаковое 16 бит
int + Int32 -2'147'483'648 —2'147'483'647 Знаковое 32 бит
uint - UInt32 0 —4'294'967'295 Беззнаковое 32 бит
long + Int64 -9'223'372'036'854'775'808 —9'223'372'036'854'775'807 Знаковое 64 бит
ulong - UInt64 0 —18'446'774'073'709'551'615 Беззнаковое 64 бит
char + Char U+0000 —U+FFFF Для описания только одного символа Unicode 16 бит
float + Single 1.5x10-45 —3.4x1038 Знаковое с плавающей точкой 32 бит
double + Double 5.0x10-324— 1.7x10308 Знаковое с плавающей точкой 64 бит
bool + Boolean true или false Логическое
decimal + Decimal 100 —1028 Знаковое 96 бит
string + String Ограничено только системной памятью Для описания строки символов Unicode любой длины
object + Object Практически все что угодно. Все типы происходят от System.Object, поэтому объектом является все Класс, базовый для всех типов в . NET

Из приведенных в таблице типов только часть является CLR -совместимой. Если мы создаем приложение, которое должно работать в многоязыковой среде, то желательно ограничиться только CLS -совместимыми типами. Этим мы гарантируем, что наши классы, интерфейсы и структуры будут нормально работать с любым языком . NET.

Системные типы как классы можно посмотреть в суфлере кода IntelliSense, написав в текстовом редакторе слово System и точку


То же самое можно получить, выполнив команду запуска IntelliSense как показано на картинке


То же самое можно получить, написав в текстовом редакторе кода внутри любого метода ключевое слово new


Во всех случаях при этом нужно, чтобы курсор конструктивно находился внутри какого-нибудь метода класса или структуры.

Поскольку тип int - это всего лишь более простая и удобная запись системного типа Int32, то и с числовыми константами можно обращаться как с переменными соответствующего типа. Ниже приведен пример допустимого синтаксиса

using System;
  
namespace Test
{
class Test
{
}
  
class App
{
static void Main()
  {
  Console.WriteLine("ToString(): {0}", 1234567.ToString());

  while(true);
  }
}
}
Листинг 20.21 . Пример обращения с числом как с переменной

Результат выполнения примера

ToString(): 1234567

Большинство встроенных типов являются структурными типами, потому что происходят не от базового типа System.Object напрямую, а от производного от System.Object типа System.ValueType. Этот класс-надстройка нужен как раз для того, чтобы переменные системных типов были структурными и представлялись значением, а не ссылкой. Приведем пример

using System;
  
namespace Test
{
class App
{
static void Main()
{
  System.Int32 xInt = 100;
  System.Int32 yInt = 100;
  System.Object xObj = 1000;
  System.Object yObj = 1000;
        
  // Сравниваются значения
  if(xInt == yInt)
    Console.WriteLine("Значения одинаковые");
  else
    Console.WriteLine("Значения различаются");
  
  // Сравниваются ссылки
  if(xObj == yObj)
    Console.WriteLine("Ссылки одинаковые");
  else
    Console.WriteLine("Ссылки различаются");

  while(true);
}
}
}
Листинг 20.22 . Сравнения пар переменных структурных и ссылочных типов

Результат выполнения примера

Значения одинаковые 
Ссылки различаются

Системные типы как классы имеют свои методы и свойства


Отметим удобные свойства MaxValue и MinValue, которые содержат пределы поддерживаемого данным типом числового диапазона. Составим для иллюстрации небольшой тест для типа System.Double (псевдоним в C# - double )

using System;
  
namespace Test
{
class App
{
static void Main()
{
// Работаем как со структурным типом
System.Double dPI = System.Math.PI;
double dE = Math.E;
      
// Используем свойства и перегруженные методы
// структурного типа System.ValueType
Console.WriteLine("\tОбъект PI:");
Console.WriteLine("MinValue: \t{0}", System.Double.MinValue);
Console.WriteLine("MaxValue: \t{0}", System.Double.MaxValue);
Console.WriteLine("String Value: \t{0}", dPI.ToString());
Console.WriteLine("Value: \t\t{0}", dPI);
Console.WriteLine("TypeName: \t{0}", dPI.GetType().ToString());

Console.WriteLine("\n\tОбъект E:");
Console.WriteLine("MinValue: \t{0}", double.MinValue);
Console.WriteLine("MaxValue: \t{0}", double.MaxValue);
Console.WriteLine("String Value: \t{0}", dE.ToString());
Console.WriteLine("Value: \t\t{0}", dE);
Console.WriteLine("TypeName: \t{0}", dE.GetType().ToString());
  
while(true);
}
}
}
Листинг 20.23 . Проверка свойств и методов типа double

Результат выполнения примера

Объект PI:
MinValue:   -1,79769313486232E+308 
MaxValue:   1,79769313486232E+308 
String Value:  3,14159265358979 
Value:     3,14159265358979 
TypeName:   System.Double
  
  Объект E:
MinValue:   -1,79769313486232E+308 
MaxValue:   1,79769313486232E+308 
String Value:  2,71828182845905 
Value:     2,71828182845905 
TypeName:   System.Double

Следует отметить, что логический тип System.Boolean (или псевдоним bool ) ожидают только логические значения true или false. Никакие числовые значения им присваивать нельзя. Для текстовых данных в C# используются только два типа: string и char. Никакие другие разновидности наподобие char*, wchar_t*, LPSTR, LPCSTR, BSTR, OLECHAR и другие в C# не допустимы. Тип char описывает только одиночный символ Unicode (char symbol = 'П';), тип string описывает строку (набор) символов Unicode любой длины.

Если создаются переменные встроенных типов внутри класса (а не внутри метода класса), то компилятор при создании экземпляра сразу инициализирует этот экземпляр подходящим значением по умолчанию. Запустите следующий код в режиме отладки Debug, предварительно поставив точку останова на последнем операторе функции Main().

using System;
  
namespace Test
{
class DefValObject
{// Переменные встроенных типов создаются внутри класса
  sbyte  theSByte;
  byte  theByte;
  short  theShort;
  ushort  theUShort;
  int    theInt;
  uint  theUInt;
  long  theLong;
  ulong  theULong;
  char  theChar;
  float  theFloat;
  double  theDouble;
  bool  theBool;
  decimal  theDecimal;
  string  theString;
  object  theObject;
}
  
class App
{
static void Main()
{
  DefValObject val = new DefValObject();
      
  while(true); // Здесь поставим точку останова для отладчика
}
  }
}
Листинг 20.24 . Инициализация встроенных типов производится автоматически

После останова программы в точке останова Breakpoint выполните последовательность нажатий клавиш < Ctrl+Alt+V, L >, чтобы вызвать окно Locals оболочки. Мы видим, что данные встроенных типов после создания объекта инициализируются.


Но если переменные встроенных типов создаются внутри какого-нибудь метода класса, то выполняется точно такая же автоматическая инициализация этих переменных.

Проверим это на подобном примере, только определения переменных перенесем внутрь метода класса.

using System;
  
namespace Test
{
class DefValObject
{
public void MyMethod() // Переменные внутри метода
{
  sbyte  theSByte;
  byte  theByte;
  short  theShort;
  ushort  theUShort;
  int    theInt;
  uint  theUInt;
  long  theLong;
  ulong  theULong;
  char  theChar;
  float  theFloat;
  double  theDouble;
  bool  theBool;
  decimal  theDecimal;
  string  theString;
  object  theObject;
  return;// Здесь поставим точку останова для отладчика
}
}
  
class App
{
  static void Main()
  {
  DefValObject val = new DefValObject();
  val.MyMethod();
  }
}
}
Листинг 20.25 . Инициализация встроенных типов производится автоматически

< Лекция 19 || Лекция 20: 1234567891011
Максим Филатов
Максим Филатов

Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет:

Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.

 

Как активировать код?