Жюссьё, Жозеф де
- 1 year ago
- 0
- 0
Cω (произносится: си́ оме́га , обычно записывается: Cw или Comega ) — язык программирования, расширение языка программирования C# , разработанный Microsoft Research . Ранее был известен под кодовыми названиями X# и Xen, было переименовано в Cω после интеграции с — ещё одним разрабатываемым языком.
Целью Cω является предоставление естественного доступа к внешним источникам полуструктурированных и структурированных данных, например, базам данных или XML-документам , столь же удобного, как и к традиционным типам данных (например, как к строке или массиву). Многие идеи были унаследованы из более раннего проекта X#. Cω также включает новые структурные компоненты для поддержки параллельного программирования; эти особенности были в значительной степени заимствованы из ранней стадии .
Особенности языка были использованы для создания компонента LINQ в .NET Framework, компоненты параллельного программирования, в слегка изменённой форме, распространяются как для C# и других .NET-языков.
Язык описывается Microsoft как строго типизированный, ориентированный на работу с данными, и призванный объединить полуструктурированные данные ( XML ), реляционные данные ( SQL ) и .NET CTS .
Примеры интеграции синтаксиса языка с данными:
choice
(или для «
|
» в
DTD
)
;
xs:sequence
в
XML Schema
Поток
(
англ.
stream
) в Cω — это, так же как и массив, набор однотипных объектов. В отличие от данных в массиве, данные в потоке создаются непосредственно при обращении к нему, с помощью
генераторов
. Синтаксически генератор выглядит так же как и обыкновенный метод, за исключением того, что генератор может выдавать несколько объектов. Тип потока объявляется добавлением звездочки после имени типа —
T*
.
// Генератор потока
int* OneToTen() {
for (int i = 1; i <= 10; i++) yield return i;
}
// Использование генератора для вывода потока
int* IntStream = OneToTen();
foreach(int j in IntStream) {
Console.WriteLine(j);
};
Тип выбора
определяется ключевым словом
choice
, и указывает на то, что данные могут быть определены разным способом. Например, объявление структуры
Address
:
struct Address {
struct{
choice { string Street; int POBox; };
string City;
int? ZipCode;
string Country;
};
}
означает, что в ней может храниться либо название улицы как строка (
string Street
), либо номер абонементного почтового ящика как число (
int POBox
), но не оба одновременно. Обращение к члену
Address::Street
вернет либо строку с названием улицы, если структура содержит её, либо
null
, если структура содержит номер абонементного почтового ящика.
Имя класса при объявлении переменной может быть записано в виде
T?
. При таком объявлении, в случае доступа к членам класса в неинициализированном объекте, не будет генерироваться null-reference-исключение, а вместо этого вернется значение
null
.
Button b = null;
bool d = b.AllowDrop; // NullReferenceException
Button? b = null;
bool? d = b.AllowDrop; // возвращает null
Анонимные типы соответствуют элементу
xs:sequence
в
XML Schema
. Анонимные структурные типы похожи на обычные структурные типы в C#, но имеют ряд существенных отличий:
struct{ int; string; string; DateTime date; string;} x =
new {47, "Hello World", "Dare Obasanjo", date=DateTime.Now, "This is my first story"};
Console.WriteLine(x[1]); // Hello World
В Cω можно создавать объекты с помощью XML-синтаксиса, при этом XML-сущности могут содержать встроенный код для вычисления значения. Однако, так как Cω строго типизированный язык, имена членов объекта, а также их типы должны быть известны при компиляции. Пример ниже показывает как можно использовать XML-синтаксис:
public class NewsItem {
attribute string title;
struct { DateTime date; string body; }
public static void Main() {
NewsItem news = <NewsItem title="Hello World">
<date>{DateTime.Now}</date>
<body>I am the first post of the New Year.</body>
</NewsItem>;
Console.WriteLine(news.title + " on " + news.date);
}
}
С появлением потоков и анонимных структур, которые могут содержать несколько членов с одинаковым именем, даже обыкновенный доступ к члену при помощи оператора точки в Cω можно рассматривать как запрос. Например,
books.Book.title
вернёт свойства
title
всех объектов
Book
из класса
books
.
Оператор «
.*
» используется для получения всех полей в типе. Например,
books.Book.*
возвращает поток всех членов всех объектов
Book
из класса
books
.
Cω также поддерживает транзитивный доступ к членам через оператор «
…
». Операция
books…title
возвращает поток, содержащий все члены
title
, которые содержатся в классе
books
, или в его содержимом (по рекурсии). Оператор транзитивного доступа так же может быть использован для доступа к членам определённого типа:
…typename::*
. Например,
books…string::*
возвращает поток, содержащий все члены типа
string
, содержащиеся в классе
books
, или в его содержимом (по рекурсии).
К результатам оператора транзитивного доступа можно применить фильтрацию. Фильтр применяется к запросу используя оператор «
[expression]
».
struct {int a; int b; int c;} z = new {a=5, b=10, c=15};
int* values = z…int::*[it > 8];
foreach(int i in values){
Console.WriteLine(i + " is greater than 8");
}
Cω вводит следующие SQL-операции как ключевые слова языка:
select, from
);
distinct, top, where
);
order by, asc, desc
);
group by, having, Count, Min, Max, Avg, Sum, Stddev
);
inner join, left join, right join, outer join
);
insert, update, delete, transact, commit, rollback
);
Такой подход позволяет работать с данными используя SQL-подобные запросы.
public class Test{
enum CDStyle {Alt, Classic, HipHop}
static struct{ string Title; string Artist; CDStyle Style; int Year;}* CDs = new{
new{ Title="Lucky Frog", Artist="Holly Holt", Style=CDStyle.Alt, Year=2001},
new{ Title="Kamikaze", Artist="Twista", Style=CDStyle.HipHop, Year=2004},
new{ Title="Stop Light Green", Artist="Robert O'Hara", Style=CDStyle.Alt, Year=1981},
};
public static void Main(){
struct { string Title; string Artist;}* results;
results = select Title, Artist from CDs where Style == CDStyle.HipHop;
results.{ Console.WriteLine("Title = {0}, Artist = {1}", it.Title, it.Artist); };
}
}