Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: .NET 2.0 - синтаксические особенности  (Прочитано 7027 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« : 03-10-2006 08:52 » 

Вот я до него добрался и делюсь впечатлениями.

В общем, неплохо.

1) Nullable классы, например:
Код: (Text)
int? x = null;
x = 20;
int y = x ?? -1;
Оператор ?? разворачивается в
Код: (Text)
int y = x != null ? x : -1;

2) Параметризация классов. Здесь ничего нового по сравнению с C++.
Код: (Text)
class X<T>
{
  private T y;
  ...
}
Параметры классов можно типизировать:
Код: (Text)
class X<T> where T : Y
{
  private T y;
  ...
}

3) Разделяемые классы - подобно пространствам имён
Код: (Text)
partial class X
{
  public int a;
}
partial class X
{
  public int b;
}

...

X x = new X();
x.a = 1;
x.b = 2;
Части класса могут быть раскиданы по разным файлам. По-моему, такое новшество может быть использовано как во благо (в случае реализации множества интерфейсов в одном классе), так и во зло (когда программные модули раскиданы неизвестно где).

Вот что вызывает противоречивые чувства, так это конструкции yield.
Операторы "yield return" и "yield break" используются для простой реализации обхода данных в цикле foreach. Написал для себя пример обхода несбалансированного бинарного дерева.
Код: (Text)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace Test
{
    class Program
    {
        static void Main()
        {
            Random random = new Random(
                Convert.ToInt32(
                    (Convert.ToInt64(DateTime.Now.Ticks) << 32) >> 32
                ));
            Tree<int> tree = new Tree<int>();
            for (int i = 1; i <= 0; ++i)
            {
                int x = random.Next(100);
                Console.Write(x.ToString() + " ");
                tree.Add(x);
            }
            Console.WriteLine();
            foreach (int i in tree.WalkAround())
                Console.Write(i.ToString() + " ");
            Console.ReadLine();
        }
    }

    class Tree<T> where T : IComparable<T>
    {
        private TreeNode<T> root;

        public Tree()
        {
            this.root = null;
        }

        public void Add(T item)
        {
            if (root == null)
                this.root = new TreeNode<T>(item);
            else
                this.root.AddChild(item);
        }

        public IEnumerable<T> WalkAround()
        {
            if (this.root != null)
                foreach (T i in this.root.WalkAround())
                    yield return i;
            else
                yield break;
        }
    }
   
    class TreeNode<T> where T : IComparable<T>
    {
        private TreeNode<T> leftChild;
        private TreeNode<T> rightChild;
        private T item;

        public TreeNode(T item)
        {
            this.leftChild = null;
            this.rightChild = null;
            this.item = item;
        }

        public void AddChild(T item)
        {
            if (item.CompareTo(this.item) < 0)
                if (this.leftChild == null)
                    this.leftChild = new TreeNode<T>(item);
                else
                    this.leftChild.AddChild(item);
            else
                if (this.rightChild == null)
                    this.rightChild = new TreeNode<T>(item);
                else
                    this.rightChild.AddChild(item);
        }

        public IEnumerable<T> WalkAround()
        {
            if (this.leftChild != null)
                foreach (T i in this.leftChild.WalkAround())
                    yield return i;
            yield return this.item;
            if (this.rightChild != null)
                foreach (T i in this.rightChild.WalkAround())
                    yield return i;
        }
    }
}

Операторы yield return и yield break работают таким образом, что прерывают исполнение методов на каждой итерации, т.е. фактически в программе одновременно выполняется множество циклов с периодическими переходами между ними при помощи замаскированных goto. Оно может и удобно для рекурсивных алгоритмов, вроде описанного выше, но с точки зрения понятности программы... мне кажется, такая конструкция вредна. По крайней мере создатели языка явно не сторонники Дейкстры и не читали "Дисциплину программирования". Каким образом доказывать корректность таких программ, я пока не знаю.

Остальные синтаксические нововедения мелкие и внимания, по-моему, не заслуживают. Например, "static class", предписывающий в классе объявлять только статические члены, запрещающий наследование такого класса и запрещающий создание объектов такого класса. Может ещё чего есть.
« Последнее редактирование: 03-10-2006 14:56 от dimka » Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
RussianGeek
Гость
« Ответ #1 : 14-12-2006 07:21 » 

Есть еще пару вещей интересных.
1) Анонимные методы
2) Partial types - не знаю, как правильно на русском
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines