Структуры и перечисления. Упаковка и распаковка в структурах

Страницы работы

Фрагмент текста работы

Структуры и перечисления

Перечисления С#

  • Перечисление задает конечное множество возможных значений, которые могут получать объекты класса перечисление.
  • [атрибуты][модификаторы] enum имя_перечисления
  • [: базовый класс]
  • {список_возможных_значений}
  • перечисления могут быть объявлены непосредственно в пространстве имен проекта или могут быть вложены в описание класса;
  • константы разных перечислений могут совпадать. Имя константы всегда уточняется именем перечисления, например, EmpType.Manager ;
  • константы могут задаваться словами русского языка;
  • разрешается задавать базовый класс перечисления;
  • разрешается задавать значения элементам перечисления.
  • enum EmpType {
  • Manager = 10, Grunt = 1,Contractor = 100,VP = 99
  • }

Базовый класс System.Enum

  • GetUnderlyingType() – возвращает тип данных, используемый для представления числовых значений элементов перечисления:
  • Console.WriteLine(Enum.GetUnderlyingType(typeof(EmpType)));
  • Enum.Format() - возвращает значимые имена элементов перечисления по их числовым значениям :
  • EmpType fred;
  • fred = EmpType.Contractor;
  • Console.WriteLine("You area {0}”, Enum.Format(typeof(EmpType), fred, "G"));

Базовый класс System.Enum

  • GetValues() - возвращает экземпляр System.Array, где значениями являются члены указанного перечисления :
  • Array obj = Enum.GetValues(typeof(EmpType));
  • foreach(EmpType e in obj) {
  • Console.Write("String name: {0}", Enum.Format(typeof(EmpType), e, "G"));
  • Console.Write( “({0})", Enum.Format(typeof(EmpType), e, "D"));
  • }
  • свойство IsDefined- позволяет определить, является ли символьная строка элементом указанного перечисления
  • if(Enum.IsDefined(typeof(EmpType), "SalesPerson")) . . .

Структуры в С#

  • могут определять конструкторы (только с параметрами);
  • могут реализовывать интерфейсы;
  • могут содержать любое количество внутренних членов.
    • [атрибуты][модификаторы] struct имя_структуры
    • [:список_интерфейсов]
    • {тело_структуры}
    • struct Employee {
      • public EmpType title; // поле – перечисление
      • public string name;
      • public short deptID;
    • }
    • class StructTester {
      • public static void Main(string[] args) {
        • Employee fred;
        • fred.deptID = 40;
        • fred.name = "Fred";
        • fred.title = EmpType.Grunt;
    • }
    • }

Конструкторы в структурах

struct Employee { . . . // Конструктор public Employee (EmpType et, string n, short d) { title = et; name = n; deptID = d; } } class StructTester { public static void Main(string[] args) { // Для вызова конструктора используется new Employee maгу =new Employee (EmpType.VP, "Mary", 10); } public void Displ ayEmpStats (Employee e) { Console.WriteLine(“Here is {0}\'s info:", e.name); Console.WriteLine("Department ID: {0}", e.deptID); Console.WriteLine(“Title: {0}", Enum.Format(typeof(EmpType), e.title, "G")); } }

Упаковка и распаковка в структурах

// Создаем и упаковываем нового сотрудника Employee stan = new Employee (EmpType.Grunt, "Stan", 10); object stanlnBox = stan; public void UnboxThisEmployee(object о) { // Распаковка в структуру Employee для получения доступа ко всем полям Employee temp = (Employee)o; Console.WriteLine(temp.name + "is alive!"); }

Процедуры и функции

  • Функция отличается от процедуры двумя особенностями:
  • всегда вычисляет некоторое значение, возвращаемое в качестве результата функции;
  • вызывается в выражениях.
  • Процедура C# имеет свои особенности:
  • возвращает формальный результат void, указывающий на отсутствие результата;
  • вызов процедуры является оператором языка;
  • имеет входные и выходные аргументы, причем выходных аргументов - ее результатов - может быть достаточно много.

Методы класса

  • [атрибуты][модификаторы]
  • void | тип_результата_функции имя_метода ([список_формальных_аргументов]) { тело метода}
  • Список формальных аргументов
  • входные
  • выходные
  • обновляемые.
  • [ref|out|params] тип имя_аргумента
  • ref – обновляемый параметр
  • out – выходной параметр
  • params – переменное число параметров

// Аргументы могут быть разного типа. void A(out long p2, int p1) { p2 =(long) Math.Pow(p1,3); Console.WriteLine("Метод A-1"); } void A(out long p2, params int[] p) { p2=0; for(int i=0; i <p.Length; i++) p2 += (long)Math.Pow(p[i],3); Console.WriteLine("Метод A-2"); } Вызов: long value; A(out value, 3); A(out value, 3,4,7,9,2,1);

Функции с побочным эффектом

Функция называется функцией с побочным эффектом, если помимо результата, вычисляемого функцией и возвращаемого ей в операторе return, она имеет выходные аргументы с ключевыми словами ref и out. int f(ref int a) { return(a++); } public void TestSideEffect() { // тестирование int a = 0, b=0, c=0; a =1; b = a + f(ref a); a =1; c = f(ref a)+ a; Console.WriteLine("a={0}, b={1}, c={2}",a,b,c); }

Классы в С#

Классы

  • Две сущности класса:
    • Класс – это модуль, архитектурная единица.
    • Класс – это тип данных.
  • [атрибуты][модификаторы] class имя_класса [:список_родителей]
  • {тело_класса}
  • Модификаторы: abstract, sealed, private, protected, public, internal
  • В теле класса могут быть объявлены:
  • константы;
  • поля;
  • конструкторы и деструкторы;
  • методы;
  • свойства;
  • индексаторы;
  • события;
  • делегаты;
  • вложенные классы (структуры, интерфейсы, перечисления).

class Employee { private string fullName; private int empID; private float currPay; public Employee() {} public Employee(string fullName, int empID, float currPay) { this. fullName = fullName; this.empID = empID; this. currPay = currPay; } public void GiveBonus(float amount) { currPay += amount; } public virtual void DisplayStats() { Console. WriteLine("Name: {0}", fullName); Console.WriteLine(“Pay: {0}", currPay); Console.WriteLine(“ID: {0}", empID); } } public static void Main() { Employee e = new Employee(“Joe", 80, 30000); e.GiveBonus(200); Employee e2; // ссылка на объект e2 = new Employee("Beth", 81, 50000); e2.GiveBonus(1000); e2.DisplayStats(); }

Методы-свойства (Properties)

  • Реализуют стратегии доступа к полю:
  • чтение, запись (Read, Write);
  • чтение, запись при первом обращении (Read, Write-once);
  • только чтение (Read-only);
  • только запись (Write-only);
  • ни чтения, ни записи (Not Read, Not Write).

public class Person { string fam="", status="", health=""; int age=0, salary=0; public string Fam { //стратегия: Чтение, запись при первом обращении set {if (fam == "") fam = value;} get {return(fam);} } public string Status { //стратегия: Только чтение get {return(status);} } public int Age { //стратегия: Чтение, запись set { age = value; if(age < 7) status ="ребенок"; else if(age <17) status ="школьник"; else if (age < 22) status = "студент"; else status = "служащий"; } get {return(age);} } public int Salary { //стратегия: Только запись set {salary = value;} } }

Автоматически реализуемое свойство тип имя {get; set;} public int UserCount { get; set;} // доступ только по чтению public int UserCount { get; private set;}

Индексаторы

….. const int Child_Max = 10; //максимальное число детей Person[] children = new Person[Child_Max]; int count_child=0; //число детей public Person this[int i] { //индексатор get { if (i>=0 && i< count_child) return(children[i]); else return(children[0]); } set { if (i==count_child && i< Child_Max) { children[i] = value; count_child++; } } } public int Count_child { get {return (count_child);} }

public void TestPersonChildren(){ Person pers1 = new Person(), pers2 = new Person(); pers1.Fam = "Петров"; pers1.Age = 42; pers1.Salary = 10000; pers1[pers1.Count_child] = pers2; pers2.Fam ="Петров"; pers2.Age = 21; pers2.Salary = 1000; Person pers3= new Person("Петрова"); pers1[pers1.Count_child] = pers3; pers3.Fam ="Петрова"; pers3.Age = 5; Console.WriteLine ("Фам={0}, возраст={1}, статус={2}", pers1.Fam, pers1.Age, pers1.Status); Console.WriteLine ("Сын={0}, возраст={1}, статус={2}", pers1[0].Fam, pers1[0].Age, pers1[0].Status); Console.WriteLine ("Дочь={0}, возраст={1}, статус={2}", pers1[1].Fam, pers1[1].Age, pers1[1].Status); }

Конструкторы и деструктор

Person pers1 = new Person(); Person pers3= new Person("Петрова"); static Person(){ Console.WriteLine("Выполняется статический конструктор!"); } ~Person(){ //Код деструктора }

Проектирование класса Rational

class Rational { int m, n; public Rational(int a, int b){ if(b==0) {m=0; n=1;} else { if( b<0) {b=-b; a=-a;} //приведение знака int d = nod(a,b); //приведение к несократимой дроби m=a/d; n=b/d; } } int nod(int m, int n){ // НОД int p=0; m=Math.Abs(m); n =Math.Abs(n); if(n>m){p=m; m=n; n=p;} do { p = m%n; m=n; n=p; }while (n!=0); return(m); } public void PrintRational(string name){ Console.WriteLine(" {0} = {1}/{2}",name,m,n);}

public Rational Plus(Rational a){ int u,v; u = m*a.n +n*a.m; v= n*a.n; return( new Rational(u, v)); } public static Rational operator +(Rational r1, Rational r2) { return (r1.Plus(r2)); } public Rational Minus(Rational a){ int u,v; u = m*a.n - n*a.m; v= n*a.n; return( new Rational(u, v)); } public static Rational operator -(Rational r1, Rational r2) { return (r1.Minus(r2)); } public static readonly Rational Zero, One; private Rational(int a, int b, string t){ m = a; n = b; } static Rational(){ Console.WriteLine("static constructor Rational"); Zero = new Rational(0, 1, "private"); One = new Rational (1, 1, "private"); }

public static bool operator ==(Rational r1, Rational r2){ return((r1.m ==r2.m)&& (r1.n ==r2.n)); } public static bool operator !=(Rational r1, Rational r2){ return((r1.m !=r2.m)|| (r1.n !=r2.n)); } public static bool operator <(Rational r1, Rational r2){ return(r1.m * r2.n < r2.m* r1.n); } public static bool operator >(Rational r1, Rational r2){ return(r1.m * r2.n > r2.m* r1.n); } public static bool operator <(Rational r1, double r2){ return((double)r1.m / (double)r1.n < r2); } public static bool operator >(Rational r1, double r2){ return((double)r1.m / (double)r1.n > r2); } static void Main(){ Rational r1 = new Rational(2,8), r2 =new Rational(2,5); Rational r3 = new Rational(4, 10), r4 = new Rational(3,7); Rational r5 = Rational.Zero, r6 = Rational.Zero; if ((r1 != Rational.Zero) && (r2 == r3)) r5 = (r3+Rational.One)-r4; r6 = Rational.One + Rational.One; r5.PrintRational("r5: ((r3 +1)-r4)"); // 34/35 r6.PrintRational("r6: (1+1)"); // 2/1 }}

Наследование

сlass <имя_класса_потомка>: <базовый_класс>

public class Found{ protected string name; protected int credit; public Found() { } public Found(string name, int sum) { this.name = name; credit = sum; } public virtual void VirtMethod() { Console.WriteLine ("Отец: " + this.ToString() ); } public override string ToString() { return(String.Format("поля: name = {0}, credit = {1}", name, credit)); } public void NonVirtMethod() { Console.WriteLine ("Мать: " + this.ToString() ); } public void Analysis() { Console.WriteLine ("Простой анализ"); } public void Work() { VirtMethod(); NonVirtMethod(); Analysis(); } }

public class Derived:Found { protected int debet; public Derived() {} public Derived(string name, int cred, int deb): base (name,cred){ debet = deb; } public void DerivedMethod(){ Console.WriteLine("Это метод класса Derived"); } new public void Analysis(){ base.Analysis(); Console.WriteLine("Сложный анализ"); } public override void VirtMethod(){ Console.WriteLine("Сын: " + this.ToString()); } public override string ToString(){ return(String.Format("поля: name = {0}, credit = {1},debet ={2}", name, credit, debet

Похожие материалы

Информация о работе