Разработка сайта для Вашего бизнеса. Веб дизайн. Дизайн логотипа, фирменного стиля, рекламная фотография . Комплексный рекламный креатив.

Ralex. We do the work.
На рынке с 1999го года. Средняя ценовая категория. Ориентация на эффективность решений.
Ознакомтесь с нашим портфолио
Узнайте больше о услугах
Свяжитесь с нами:
E-mail: [email protected]
Tel: (044) 587 - 84 - 78
Custom web design & дизайн и разработка сайта "под ключ"
Креативный, эффективный дизайн. Система управления сайтом (СУС).
Custom flexible разработка систем электронной коммерции
Система e-commerce разрабатывается под индивидуальные потребности. Гибкая функциональность.
Search Engine Optimzation & оптимизация под поисковые системы (SEO)
Постоянная оптимизация и мониторинг сайта в поисковых системах. Достигаем результата быстро и эффективно
Custom logo design & дизайн логотипа и фирменного стиля
Многолетний опыт. Огромное портфолио. Уникальное предложение и цена.
профессиональная рекламная фотография
креативно, смело, качественно
Custom logo design & рекламный креатив. дизайн рекламы
Многолетний опыт. Огромное портфолио. Уникальное предложение и цена.

C # 7 - Що нового

  1. C # 7 - Основний напрямок поліпшень
  2. C # 7.0 - Робота з даними
  3. Кортежі / Tuples
  4. Покращена продуктивність в C # 7.0
  5. локальні функції
  6. Локальні змінні за посиланням
  7. Продуктивність для асинхронних методів
  8. Спрощення в написанні коду в C # 7.0

Наша взаимовыгодная связь https://banwar.org/

Зовсім недавно була випущена нова версія мови програмування C #. У цій статті я розповім про основні нововведення в новій версії C # 7.

C # 7 - Основний напрямок поліпшень

У всіх попередніх випусках C # (можливо за винятком C # 6), все поліпшення були зосереджені навколо деякої основної теми:
C # 2.0 - вводяться Generic типи.
C # 3.0 - додається LINQ за допомогою впровадження методів розширень (extension methods), додаються лямбда виразу, анонімні типи і інші поліпшення, необхідні для зручної роботи з LINQ.
C # 4.0 - все поліпшення зосереджені на поліпшенні сумісності (interoperability) за допомогою динамічних не строго типізованих змінних (dynamic),
C # 5.0 - спрощується асинхронне програмування за допомогою додавання ключових слів async / await
C # 6.0 - повністю переписується компілятор, додаються кілька поліпшень і нових фіч.

І нова версія мови C # 7.0 не виняток. Розробники компілятора зосередилися на трьох основних напрямках:

Робота з даними - популярність веб-служб призводить до зміни способу моделювання даних. Замість того, щоб розробляти моделі даних як частина програми, їх визначення стає частиною контрактів веб-сервісів. Хоча це дуже зручно в функціональних мовах, це може принести додаткову складність в об'єктно-орієнтовану розробку додатків. Кілька нових функцій C # 7.0 націлені на спрощення роботи з контрактами зовнішніх даних.

Покращена продуктивність - зростання частки додатків для мобільних пристроїв робить свій вплив, і тепер компілятор повинен генерувати високопродуктивний код, який може швидко і надійно виконуватися на мобільних платформах. В C # 7.0 представлені функції, які дозволяють оптимізувати продуктивність, які раніше були недоступні для платформи .NET.

Спрощення коду - новий компілятор вносить кілька додаткових невеликих змін, заснованих на розробках для C # 6.0, які дозволяють ще більше спростити написання якісного і красивого код.

C # 7.0 не підтримуються в Visual Studio 2015 (і відповідно більш ранніми версіями).
Щоб почати використовувати нові функції, вам необхідно завантажити та встановити Visual Studio 2017.

А тепер давайте розглянемо докладніше всі ці нові функції.

C # 7.0 - Робота з даними

Об'єктно-орієнтовані мови програмування, такі як C #, відмінно підходять для випадків, коли потрібна робота з розширюваним набором типів даних за допомогою визначеного набору операцій. Зазвичай вони моделюються за допомогою інтерфейсу (або базового класу), що визначає доступні операції і потенційно зростаючий набір класів, що представляють типи даних. Реалізуючи інтерфейс, класи містять реалізацію всіх очікуваних операцій, які можуть бути зроблені над об'єктом.

Наприклад, в комп'ютерній грі класами можуть бути представлені різні види зброї (наприклад, меч або цибуля), а операції над об'єктами зброї можуть бути різні дії (такі як атака або ремонт). В цьому випадку додавання нового типу зброї (наприклад, світловий меч) дуже проста операція: просто створіть новий клас, який реалізує інтерфейс зброї. З іншого боку, додавання нового дії (наприклад, чистка зброї) зажадає розширення інтерфейсу і зміни всіх існуючих реалізацій зброї.

interface IEnemy {int Health {get; set; }} Interface IWeapon {int Damage {get; set; } Void Attack (IEnemy enemy); void Repair (); } Class Sword: IWeapon {public int Damage {get; set; } Public int Durability {get; set; } Public void Attack (IEnemy enemy) {if (Durability & gt; 0) {enemy.Health - = Damage; Durability--; }} Public void Repair () {Durability + = 100; }} Class Bow: IWeapon {public int Damage {get; set; } Public int Arrows {get; set; } Public void Attack (IEnemy enemy) {if (Arrows & gt; 0) {enemy.Health - = Damage; Arrows--; }} Public void Repair () {}}

У функціональному програмуванні типи даних не містять операції. Замість цього кожна функція реалізує єдину операцію для всіх типів даних. Це значно спрощує додавання нової операції (просто визначити і впровадити нову функцію), але ускладнює додавання нового типу даних (необхідно модифікувати всі існуючі функції). Програмування в такому стилі вже було можливо в C # 6, хоча код виходить набагато більш громіздким, ніж могло б бути.

interface IEnemy {int Health {get; set; }} Interface IWeapon {int Damage {get; set; }} Class Sword: IWeapon {public int Damage {get; set; } Public int Durability {get; set; }} Class Bow: IWeapon {public int Damage {get; set; } Public int Arrows {get; set; }} Static class WeaponOperations {static void Attack (this IWeapon weapon, IEnemy enemy) {if (weapon is Sword) {var sword = weapon as Sword; if (sword.Durability> 0) {enemy.Health - = sword.Damage; sword.Durability--; }} Else if (weapon is Bow) {var bow = weapon as Bow; if (bow.Arrows> 0) {enemy.Health - = bow.Damage; bow.Arrows--; }}} Static void Repair (this IWeapon weapon) {if (weapon is Sword) {var sword = weapon as Sword; sword.Durability + = 100; }}}

Pattern matching - це функція, яка повинна допомогти спростити наведений вище код. Нижче приклад, як це може виглядати якщо застосувати його до методу Attack ():

static void Attack (this IWeapon weapon, IEnemy enemy) {if (weapon is Sword sword) {if (sword.Durability> 0) {enemy.Health - = sword.Damage; sword.Durability--; }} Else if (weapon is Bow bow) {if (bow.Arrows> 0) {enemy.Health - = bow.Damage; bow.Arrows--; }}}

Замість того, щоб перевіряти тип зброї і призначати його правильної типизированной змінної в двох окремих операціях, тепер оператор is також дозволяє нам оголосити нову змінну і привласнити їй значення типу.

З аналогічним результатом можна використовувати оператор case switch замість if. Це може зробити код ще більш зрозумілим, особливо коли є багато різних гілок:

switch (weapon) {case Sword sword when sword.Durability> 0: enemy.Health - = sword.Damage; sword.Durability--; break; case Bow bow when bow.Arrows> 0: enemy.Health - = bow.Damage; bow.Arrows--; break; }

Зверніть увагу, як оператор case виконує як привласнення типу, так і додаткову умовну перевірку, роблячи код набагато більш компактним і зрозумілим.

Кортежі / Tuples

Існує ще одна нова фіча в C # 7.0, яка повинна сприяти створенню більш компактного коду: кортежі (tuples). Це нова, більш легка альтернатива анонімним класах. Їх основне використання, ймовірно, буде в функціях, які повертають кілька значень, в якості альтернативи аргументів з модифікатором out. приклад:

public static (int weight, int count) Stocktake (IEnumerable <IWeapon> weapons) {var w = 0; var c = 0; foreach (var weapon in weapons) {w + = weapon.Weight; c ++; } Return (w, c); }

ВАЖЛИВО: Щоб використовувати кортежі, вам необхідно встановити NuGet пакет System.ValueTuple, який додає необхідний тип System.ValueType <> узагальненого типу.

ValueType <> узагальненого типу

Установка NuGet пакет для підтримки System.ValueTuple

Метод вище повертає два окремих значення без використання аргументів з модифікатором out і без необхідності оголошувати новий спеціальний тип або використовувати анонімну змінну. Синтаксис виклику методу залишається тим самим:

static void Main (string [] args) {List <IWeapon> inventory = new List <IWeapon> (); Sword sword = new Sword (); sword.Damage = 100; sword.Durability = 200; sword.Weight = 50; inventory.Add (sword); var inventoryInfo = Tuples.Stocktake ((IEnumerable <IWeapon>) inventory); Console.WriteLine ($ "Weapon count: {inventoryInfo.count}"); Console.WriteLine ($ "Total weight: {inventoryInfo.weight}"); }

Значення, що повертається схоже на узагальнений клас Tuple <> з .NET Framework. Однак є дві важливі відмінності:
1. Його члени можуть мати значущі імена, певні в викликається метод, і не обмежуються описовими Item1, Item2 і т. Д. Це робить код краще читаним і зрозумілішим.
2. Це змінна типу значення, а не змінна посилального типу. Тобто немає витрат на виділення пам'яті.
А ще, в якості альтернативи, при виклику методу можна використовувати нову функцію мови деконструкцію (deconstruction) для повернення значень в локальні змінні:

(Var inventoryWeight, var inventoryCount) = Tuples.Stocktake ((IEnumerable) inventory); Console.WriteLine ($ "Weapon count: {inventoryCount}"); Console.WriteLine ($ "Total weight: {inventoryWeight}");

В цьому випадку ви визначаєте імена для окремих членів, що повертається. Цей синтаксис дозволить ігнорувати повернені значення, які вас не цікавлять, використовуючи відкидання (зверніть увагу на використання нижнього підкреслення _ замість оголошень змінних в наведеному нижче коді):

(Var inventoryWeight2, _) = Tuples.Stocktake ((IEnumerable) inventory); Console.WriteLine ($ "Total weight: {inventoryWeight2}");

Деконструкція (deconstruction) може застосовуватися не тільки при роботі з кортежами. Будь-який тип може використовувати деконструкцію, якщо є оголошений метод деконструкції для цього типу. приклад:

public static void Deconstruct (this Sword sword, out int damage, out int durability) {damage = sword.Damage; durability = sword.Durability; }

Такий метод розширення робить наступний код цілком дійсним:

(Var damage, var durability) = sword; Console.WriteLine ($ "Sword damage rating: {damage}"); Console.WriteLine ($ "Sword durability: {durability}");

Головна умова - тип повинен містити метод з ім'ям Deconstruct, або повинен бути оголошений метод розширення з ім'ям Deconstruct.

Покращена продуктивність в C # 7.0

Покращення продуктивності в C # 7.0 зосереджені на скороченні копіювання даних між осередками пам'яті.

локальні функції

Локальні функції (Local functions) дозволяють оголошувати допоміжні функції, вкладені в інші функції. Це не тільки зменшує їх обсяг, але також дозволяє використовувати змінні, оголошені в їх охоплює області, без виділення додаткової пам'яті в купі або стеку:

static void ReduceMagicalEffects (this IWeapon weapon, int timePassed) {double CalculateDecayRate () => 0.1; double decayRate = CalculateDecayRate (); double GetRemainingEffect (double currentEffect) => currentEffect * Math.Pow (decayRate, timePassed); weapon.FireEffect = GetRemainingEffect (weapon.FireEffect); weapon.IceEffect = GetRemainingEffect (weapon.IceEffect); weapon.LightningEffect = GetRemainingEffect (weapon.LightningEffect); }

Локальні змінні за посиланням

Значення, що повертаються і локальні змінні за посиланням також можуть використовуватися для запобігання непотрібного копіювання даних. Але в той же час вони змінюють поведінку. Оскільки змінна вказує на вихідну комірку пам'яті, будь-які зміни в цьому значенні, звичайно ж, також впливають на значення локальної змінної:

public void LocalVariableByReference () {var terrain = Terrain.Get (); ref TerrainType terrainType = ref terrain.GetAt (4, 2); Assert.AreEqual (TerrainType.Grass, terrainType); // Змінити значення enum в вихідному місцезнаходження terrain.BurnAt (4, 2); // локальна змінна також була порушена і змінила своє значення Assert.AreEqual (TerrainType.Dirt, terrainType); }

У наведеному вище прикладі terrainType є локальної змінної по посиланню, а GetAt - функцією, що повертає значення за посиланням:

public ref TerrainType GetAt (int x, int y) = & gt; ref terrain [x, y];

Продуктивність для асинхронних методів

Крім того, в C # 7.0 була покращена продуктивність і для асинхронних методів.

В даний час все асинхронні методи повинні повертати Task, який є посилальним типом. Тепер доступний тип значення: ValueTask.

Якщо асинхронний метод вже має результат, доступний при виклику, це може привести до значних поліпшень продуктивності через зменшення кількості розподілів в купі.

Крім того, мова тепер дозволяє використовувати інші призначені для користувача типи повертаються даних для асинхронних методів, що може мати сенс для бібліотек з особливими вимогами.

Спрощення в написанні коду в C # 7.0

Тепер трохи поговоримо про синтаксичному цукрі.

В C # 6.0 з'явилася підтримка методів - виразів і властивостей тільки для читання. Тепер якості читання / запису, конструктори і фіналізатор також підтримують ці фічі:

class Grunt: IEnemy {// Використовуємо запис тіла конструктора у вигляді виразу public Grunt (int health) => _health = health> = 0? health: throw new ArgumentOutOfRangeException (); // Теж саме для фіналізатор - тіло методу записано у вигляді виразу ~ Grunt () => Debug.WriteLine ( "Finalizer called"); // Тіло для методів властивості також можна записувати у вигляді виразу private int _health; public int Health {get => _health = 0; set => _health = value> = 0? value: 0; }}

В цьому класі використовується ще одна нова цікава функція: throw expression. Конструктор видає виключення для від'ємних значень здоров'я. Раніше це було можливо тільки з утвердження (statement), тепер вираження також підтримують його.
Щоб передати змінну в вихідний аргумент функції до C # 7.0, вам потрібно було оголосити її заздалегідь:

ISpell spell; if (learnedSpells.TryGetValue (spellName, out spell)) {spell.Cast (enemy); }

Тепер ви можете оголосити змінну out безпосередньо в списку аргументів функції:

if (learnedSpells.TryGetValue (spellName, out var spell)) {spell.Cast (enemy); }

І останнє поліпшення, про який слід згадати, - це поліпшення числових літералів:

const int MAX_PLAYER_LEVEL = 0b0010_1010;

В C # 7.0 додана підтримка бінарних литералов. Щоб зробити їх більш чіткими, можна використовувати як роздільник цифр можна використовувати нижнє підкреслювання. А ще підкреслення можна використовувати в десяткових і шістнадцяткових літералах.
Ось такі нововведення принесла нам нова сьома версія мови C #.

Категории
  • Биология
  • Математика
  • Краеведению
  • Лечебная
  • Наука
  • Физике
  • Природоведение
  • Информатика
  • Новости

  • Новости
    https://banwar.org/
    Наша взаимовыгодная связь https://banwar.org/. Запустив новый сайт, "Пари Матч" обещает своим клиентам незабываемый опыт и возможность выиграть крупные суммы.


    Наши клиенты
    Клиенты

    Быстрая связь

    Тел.: (044) 587-84-78
    E-mail: [email protected]

    Имя:
    E-mail:
    Телефон:
    Вопрос\Комментарий: