 
        
        Лекция 1
Эволюция языка C#
По книге Дж. Скита «С# для профессионалов», 2011 г.
С# - прагматичный и быстро развивающийся язык. Наличие понятных запросов, богатство интерфейсов и типов, компактный синтаксис создают совершенно новый стиль программирования, не отказываясь от статистически типизированного, ориентированного на компоненты подхода, который обеспечил успех языка С#.
Рассматриваются изменения в синтаксических и семантических конструкциях языка. Демонстрируются несколько примеров, показывающих, какими недостатками обладал язык в более ранних версиях и как эти недостатки устраняются в более поздних. Рассматриваемые примеры являются обзором всего семестрового кода.
В качестве основных элементов исследуются обобщения, свойства с различными модификаторами доступа, типы, допускающие значение null, анонимные метод, автоматически реализуемые свойства, улучшенные инициализаторы коллекций, улучшенные инициализаторы объектов, лямбда-выражения, методы расширения, неявная типизация, выражения запросовLINQ, именованные аргументы, необязательные параметры, упрощенное взаимодействие сCOMи динамическая типизация(!).
Пример 1 . Классы и коллекции
Рассмотрим тип данных Продукт, состоящий из названия товара и его цены.
Реализация (С# 1). Реализация типа Product
using System.Collections;
class Product
{
string name;
public string Name { get { return name; } }
decimal price;
public decimal Price { get { return price; } }
public Product(string name, decimal price)
{
this.name = name;
this.price = price;
}
public static ArrayList GetSampleProducts()
{
ArrayList list = new ArrayList();
list.Add(new Product("West Side Story", 9.99m));
list.Add(new Product("Assasins", 14.99m));
list.Add(new Product("Frogs", 13.99m));
list.Add(new Product("Sweeney Todd", 10.99m));
return list;
}
public override string ToString()
{
return string.Format("{0}:{1}", name, price ); ;
}
}
static void Main(string[] args)
{
ArrayList list = Product.GetSampleProducts();
foreach (Product product in list)
Console.WriteLine(product.ToString());
Console.Read();
}
Ограничения/недостатки:
- Список ArrayListво время компиляции не имеет никакой информации о том, что в нем будет находиться. (в созданный этим методом список можно добавить элементы других типов, что будет не замечено компилятором). 
- Свойство get открыто, соответственно, если потребуется добавить свойство set, оно также автоматически будет открыто. 
- Код рассчитан на инкапсуляцию только двух свойств, но при этом является довольно тяжеловесным. 
Реализация (С# 2). Строго типизированные коллекции
Работа с обобщениями (список с указанием типа элементов); закрытые методы установки значений (которые потом используются в конструкторе). Таким образом исправлены два главных недостатка кода C#1.
using System.Collections.Generic;
class Product
{
string name;
public string Name
{
get { return name; }
private set { name = value; }
}
decimal price;
public decimal Price
{
get { return price; }
private set { price = value; }
}
public Product(string name, decimal price)
{
Name = name;
Price = price;
}
public static List<Product> GetSampleProducts()
{
List<Product> list = new List <Product>();
list.Add(new Product("West Side Story", 9.99m));
list.Add(new Product("Assasins", 14.99m));
list.Add(new Product("Frogs", 13.99m));
list.Add(new Product("Sweeney Todd", 10.99m));
return list;
}
public override string ToString()
{
return string.Format("{0}:{1}", name, price ); ;
}
}
static void Main(string[] args)
{
List<Product> list = Product.GetSampleProducts();
foreach (Product product in list)
Console.WriteLine(product.ToString());
Console.Read();
}
Код по прежнему достаточно тяжеловесен.
Реализация (С# 3). Автоматически реализуемые свойства
Представлены автоматически реализуемые свойства и упрощенная инициализация. У свойств теперь нет никакого кода, нет видимых переменных. Использование только свойств улучшает целостность класса.
Закрытый конструктор без параметров обеспечивает инициализацию на основе свойств.
class Product
{
public string Name
{
get;
private set;
}
public decimal Price
{
get;
private set;
}
public Product(string name, decimal price) // вообще говоря от него //можно отказаться
{
Name = name;
Price = price;
}
Product() { } //обеспечивает инициализацию на основе свойств
public static List<Product> GetSampleProducts()
{
return new List<Product>{
new Product {Name = "West Side Story", Price = 9.99m},
new Product {Name = "Assasins", Price = 14.99m},
new Product {Name = "Frogs1", Price = 13.99m},
new Product {Name = "Sweeney Todd",Price= 10.99m}
};
}
public override string ToString()
{
return string.Format("{0}:{1}", Name, Price ); ;
}
}
Реализация (С# 4). Именованные аргументы
За базовую возьмем версию C#1 (для свойств и конструкторов). Более однозначно указывается, у что разрабатываемого типа данных поля могут быть изменены только внутренне (readonly).
class Product
{
readonly string name;
public string Name { get { return name; } }
readonly decimal price;
public decimal Price { get { return price; } }
public Product(string name, decimal price)
{
this.name = name;
this.price = price;
}
public static List<Product> GetSampleProducts()
{
return new List<Product>{
new Product (name: "West Side Story", price: 9.99m),
new Product (name: "Assasins", price: 14.99m),
new Product (name: "Frogs1", price: 13.99m),
new Product (name: "Sweeney Todd",price: 10.99m)
};
}
Эволюция:
- Свойства только для чтения; слабо типизированные коллекции 
- Закрытые методы установки значения свойств; строго типизированные коллекции 
- Автоматически реализуемые свойства; улучшенная инициализация коллекций и объектов 
- Именованные аргументы для конструктора и вызовов методов 
