С# 3.0
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 14.09.05 16:32
Оценка: 65 (8)
Вышел первый прообраз спецификации.
Кому лень читать, вот Краткий пересказ
Автор: AndrewVK
Дата: 14.09.05
.
Здесь лабораторка, но компилятор, наверное, будет доступен только после PDC.
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re: С# 3.0
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 14.09.05 16:34
Оценка: 6 (1)
AVK>Здесь лабораторка, но компилятор, наверное, будет доступен только после PDC.

Сорри, можно скачать уже сейчас:
http://download.microsoft.com/download/4/7/0/4703eba2-78c4-4b09-8912-69f6c38d3a56/LINQ%20Preview.msi
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re: С# 3.0
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 14.09.05 16:37
Оценка:
А возможности подключения реализаций опять нет
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re: С# 3.0
От: Igor Trofimov  
Дата: 14.09.05 19:15
Оценка:
Extensions с generic'ами не живут, что в общем, понятно, но обидно:

    static class ListExt<T>
    {
        public static string First(this List<T> list)
        {
            return list[0];
        }
        public static string Last(this List<T> list)
        {
            return list[list.Count-1];
        }
    }    
    ...
    var list = new List<string> {"aaa", "bbb", "ccc"};
        
    Console.WriteLine(list.First()); // А вот тут хочется extension-свойств!


Не пашет такая попыточка. Хотя вообще-то принципиально это можно было бы сделать.
Всего лишь превращать list.First() не в ListExt<T>.First(list), а в ListExt<string>.First(list), гладя на совпадающее количество type-args.
Re: С# 3.0
От: Igor Trofimov  
Дата: 14.09.05 19:24
Оценка:
А вот интерфейсы extension'ами распознаются на ура:
    static class ListExt
    {
        public static object First(this IList list)
        {
            return list[0];
        }
        public static object Last(this IList list)
        {
            return list[list.Count-1];
        }
        public static bool Contains(this IList list, object item)
        {
            return list.Contains(item);
        }
    }
    ...
    var list = new List<string> {"aa", "bbbbb", "cccc", "dddd"};
    int[] ints = {1,2,3,4,5};

    Console.WriteLine(ints.Last());
    Console.WriteLine(list.Last());
    Console.WriteLine(list.Contains("cccc"));
    Console.WriteLine(ints.Contains(4));


Раньше для проверки вхождения элемента в массив требовалось явно приводить массив к IList.
Extension это делает сам.
Re[2]: С# 3.0
От: Igor Trofimov  
Дата: 14.09.05 19:33
Оценка: 37 (2) +1
Аааааа! Торможу!
Все там пашет:

    static class ListExt
    {
        public static T First<T>(this List<T> list)
        {
            return list[0];
        }
        public static T Last<T>(this List<T> list)
        {
            return list[list.Count-1];
        }
    }


Параметризировать надо конкретный метод а не класс.
(В предыдущем сообщении у меня вообще string затесался откуда-то )
Re: С# 3.0
От: Кодёнок  
Дата: 15.09.05 09:23
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Вышел первый прообраз спецификации.

AVK>Кому лень читать, вот Краткий пересказ
Автор: AndrewVK
Дата: 14.09.05
.

AVK>Здесь лабораторка, но компилятор, наверное, будет доступен только после PDC.

Они-таки сделали это Четвертая версия видимо обещает быть еще более интересной.
Re[2]: С# 3.0
От: Cyberax Марс  
Дата: 15.09.05 09:35
Оценка: -1
Кодёнок wrote:

> AVK>Вышел первый прообраз спецификации

> <http://download.microsoft.com/download/9/5/0/9503e33e-fde6-4aed-b5d0-ffe749822f1b/csharp%203.0%20specification.doc&gt;.
> AVK>Кому лень читать, вот Краткий пересказ
> <http://rsdn.ru/forum/Message.aspx?mid=1382740&amp;only=1&gt;
Автор: AndrewVK
Дата: 14.09.05
.

> AVK>Здесь
> <http://download.microsoft.com/download/9/5/0/9503e33e-fde6-4aed-b5d0-ffe749822f1b/csharp%203.0%20language%20enhancements%20hands%20on%20lab.doc&gt;
> лабораторка, но компилятор, наверное, будет доступен только после PDC.
> Они-таки сделали это Четвертая версия видимо обещает быть еще более
> интересной.

Ну и уродство же они с SQL в языке сделали...

--
С уважением,
Alex Besogonov (alexy@izh.com)
Posted via RSDN NNTP Server 2.0 beta
Sapienti sat!
Re[3]: С# 3.0
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 15.09.05 12:42
Оценка: +1
Здравствуйте, Cyberax, Вы писали:

C>Ну и уродство же они с SQL в языке сделали...


Это не SQL, просто на него похоже.
... << RSDN@Home 1.2.0 alpha rev. 617>>
AVK Blog
Re: С# 3.0
От: DarkGray Россия http://blog.metatech.ru/post/ogni-razrabotki.aspx
Дата: 15.09.05 19:15
Оценка: 2 (1) +1
До сих пор не хватает "красивой" работы с нулевыми значениями

сейчас вместо:
if (Root.Config.User.Age > 16)
{
   //bla-bla
}


часто приходиться писать:

int? age = null;
var root = Root;
if (root != null)
{
   var config = root.Config;
   if (config != null) 
  {
      var user = config.User;
      if (user != null) 
        age = user.Age;
   }
}
if (age != null && age.Value > 10)
{
 //bla-bla
}



т.е. хочеться иметь оператор вида '.?', который возвращает нуль, если левая часть имеет нулевое значение

if (Root.?Config.?User.?Age > 16)
{
   //bla-bla
}


или может даже лучше:
if (Root?.Config?.User?.Age > 16)
{
   //bla-bla
}



Особенно это нужно при описании правил бизнес логики, т.к. в бизнес-логики часто мы имеем на руках только частичную информацию о мире
Re[2]: С# 3.0
От: FDSC Россия consp11.github.io блог
Дата: 16.09.05 06:27
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>До сих пор не хватает "красивой" работы с нулевыми значениями


DG>т.е. хочеться иметь оператор вида '.?', который возвращает нуль, если левая часть имеет нулевое значение


DG>
DG>if (Root.?Config.?User.?Age > 16)
DG>{
DG>   //bla-bla
DG>}
DG>


DG>или может даже лучше:

DG>
DG>if (Root?.Config?.User?.Age > 16)
DG>{
DG>   //bla-bla
DG>}
DG>



Первое всё-таки лучше.

DG>Особенно это нужно при описании правил бизнес логики, т.к. в бизнес-логики часто мы имеем на руках только частичную информацию о мире


То же с этим очень мучаюсь. Просто жуть!
Re: С# 3.0
От: FDSC Россия consp11.github.io блог
Дата: 16.09.05 06:30
Оценка: :)
Здравствуйте, AndrewVK.

Я знал чем это всё кончится!


Я боюсь пользоваться продуктами Microsoft — я начинаю просто и абсолютно непонимать их стратегию.
Re[2]: С# 3.0
От: stalcer Россия  
Дата: 16.09.05 06:53
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>т.е. хочеться иметь оператор вида '.?', который возвращает нуль, если левая часть имеет нулевое значение


Интересная идея.

DG>
DG>if (Root.?Config.?User.?Age > 16)
DG>{
DG>   //bla-bla
DG>}
DG>


Пусть Root == null. Ты предлагаешь, чтобы ((RootClass)null).?Config тоже вычислялось в null? А во что же должно вычисляться все выражение Root.?Config.?User.?Age. В 0 (ноль)? И тип у него естественно будет int?
Дык, возраст со знаением ноль и возраст с неизвестным значением — это ведь две разные вещи.
А если тип будет, например, строка? возвращать пустую строку? А если структура?

Сколько народу ругается на Oracle, где пустая строка и NULL — это одно и тоже!




ИМХО, нужно вводить специальные типы, по анаголии с NULL концепцией в SQL. Так чтобы переменная этого типа могла кроме определенного знаения хранить еще и признак наличия значения, т.е. попросту говоря могла бы не иметь значения. И соответственно вводить специальные операции с такими типами.

Я в своем DSL, основа которого была нагло стырена с C#, ввел такие типы. null оставил как есть в C#, а в дополнение к этому ввел константу undefined (типа <undefined>, как и null в C# имеет специальный тип <null>).

int  x = 0;  // Обыный int.
int% y = 0;  // Как я его назвал - undefinable int.

if (defined y) // Пройдет. Аналогия с SQL-ым IS NULL.
    ...;
    
y = undefined;
    
if (y == undefined) // Не пройдет. Так как undefined != undefined, как в SQL.
    ...;
    
x = (int)y; // Требуется явное приведение. В ран-тайм будет ошибка.

y = y + x; // Выполнится как y + (int%)x. Получится undefined.


Это для простых типов. Теперь про классы с полями и свойствами:

class A
{
    public B% b;
}

class B
{
    public int x;
}

A% a = new A();
a.b  = undefined;

int% y = a.b.x; // y будет undefined. Так как a.b - undefined.
                // Несмотря на то, что поле x имеет тип int,
                // операция ((B%)somevar).x имеет тип int%.
                // но только на чтение.

a.b.x = 7;      // В ран-тайм будет ошибка. На запись a.b.x
                // имеет тип int.


Также работают свойства и индексеры.

Дык вот о птичках. Вроде в C# уже ввели работу с SQL-like типами. Там вроде какой-то стандартный дженерик есть, не помню как он там называется. С помощью такого дженерика и перегрузки операторов конечно можно имитировать работу с примитивными SQL-like типами.
А вот с полями и свойствами так как я показал — фигушки...
http://www.lmdinnovative.com (LMD Design Pack)
Re[2]: С# 3.0
От: Кодёнок  
Дата: 16.09.05 06:56
Оценка:
Здравствуйте, DarkGray, Вы писали:

DG>До сих пор не хватает "красивой" работы с нулевыми значениями

DG>сейчас вместо:
DG>if (Root.Config.User.Age > 16)
DG>часто приходиться писать:
DG>int? age = null;
DG>var root = Root;
DG>if (root != null)
DG>{
DG> var config = root.Config;
DG> if (config != null)
DG> {
DG> var user = config.User;
DG> if (user != null)
DG> age = user.Age;
DG> }
DG>}
DG>if (age != null && age.Value > 10)

Минимум наверное должен быть такой:

if ( (Root == null || Root.Config == null || Root.Config.User == null ? default_value : Root.Config.User.Age) > 10 )
...


Если бы был мощный препроцессор, можно быть бы написать универсальный макрос, принимающий конструкцию `a.b.c.*.z`, проверяющий каждый член на null и возвращающий некое значение по умолчанию в таком случае. Но вот этого в C# что-то не предвидится.
Re[3]: С# 3.0
От: FDSC Россия consp11.github.io блог
Дата: 16.09.05 07:00
Оценка: :)
Здравствуйте, stalcer, Вы писали:

S>Здравствуйте, DarkGray, Вы писали:


DG>>т.е. хочеться иметь оператор вида '.?', который возвращает нуль, если левая часть имеет нулевое значение


S>Интересная идея.


DG>>
DG>>if (Root.?Config.?User.?Age > 16)
DG>>{
DG>>   //bla-bla
DG>>}
DG>>


S>Пусть Root == null. Ты предлагаешь, чтобы ((RootClass)null).?Config тоже вычислялось в null? А во что же должно вычисляться все выражение Root.?Config.?User.?Age. В 0 (ноль)? И тип у него естественно будет int?

S>Дык, возраст со знаением ноль и возраст с неизвестным значением — это ведь две разные вещи.
S>А если тип будет, например, строка? возвращать пустую строку? А если структура?

S>Сколько народу ругается на Oracle, где пустая строка и NULL — это одно и тоже!


Я думаю, необязательно именно возвращать NULL. Можно, например, просто выходить без исключения из условного оператора, так как условие заранее не выполнено.
Re[4]: С# 3.0
От: stalcer Россия  
Дата: 16.09.05 07:07
Оценка:
Здравствуйте, FDSC, Вы писали:

DG>>>
DG>>>if (Root.?Config.?User.?Age > 16)
DG>>>{
DG>>>   //bla-bla
DG>>>}
DG>>>


FDS>Я думаю, необязательно именно возвращать NULL. Можно, например, просто выходить без исключения из условного оператора, так как условие заранее не выполнено.


Где не обязательно возвращать? Какой порядок выисления выражений то?

1) tmp1 = Root;
2) tmp2 = tmp1.?Config;
3) tmp3 = tmp2.?User;
4) tmp4 = tmp3.?Age;
5) tmp5 = tmp4 > 16;
6) if (tmp5)

Что должно быть на каждом шаге? Какого типа каждое из этих промежуточных выражений?

А если так:
int x = Root.?Config.?User.?Age;
http://www.lmdinnovative.com (LMD Design Pack)
Re[5]: С# 3.0
От: FDSC Россия consp11.github.io блог
Дата: 16.09.05 07:13
Оценка:
Здравствуйте, stalcer, Вы писали:

S>Здравствуйте, FDSC, Вы писали:


DG>>>>
DG>>>>if (Root.?Config.?User.?Age > 16)
DG>>>>{
DG>>>>   //bla-bla
DG>>>>}
DG>>>>


S>Какого типа каждое из этих промежуточных выражений?

CObject

S>Что должно быть на каждом шаге?


Компилятор должен обрабатывать примерно так:

Root.Config инициализированно? — нет — выйти из условного оператора

Root.?Config.?User инициализированно? — аналогично
Re[6]: С# 3.0
От: stalcer Россия  
Дата: 16.09.05 07:19
Оценка: :)
Здравствуйте, FDSC, Вы писали:

FDS>Здравствуйте, stalcer, Вы писали:


S>>Здравствуйте, FDSC, Вы писали:


DG>>>>>
DG>>>>>if (Root.?Config.?User.?Age > 16)
DG>>>>>{
DG>>>>>   //bla-bla
DG>>>>>}
DG>>>>>


S>>Какого типа каждое из этих промежуточных выражений?

FDS>CObject

Ну-ну. А разве CObject имеет поле Config? А? Или может быть поле User. Или может быть CObject можно сравнивать с int (c 16)? Чушь!

FDS>Root.Config инициализированно? — нет — выйти из условного оператора


FDS>Root.?Config.?User инициализированно? — аналогично


if (!(Root.?Config.?User.?Age > 16))
    ...;
    
if ((Root.?Config.?User.?Age > 16) || someBoolVar)
    ...;
    
bool x = (Root.?Config.?User.?Age > 16);


Дык откуда ты говоришь надо сразу выходить?
http://www.lmdinnovative.com (LMD Design Pack)
Re[6]: С# 3.0
От: Кодёнок  
Дата: 16.09.05 07:23
Оценка:
Здравствуйте, FDSC, Вы писали:

FDS>Компилятор должен обрабатывать примерно так:

FDS>Root.Config инициализированно? — нет — выйти из условного оператора
FDS>Root.?Config.?User инициализированно? — аналогично

Людям явно не нравится механизм обработки исключений и они ощут альтернативы

P.S. Мне тоже не нравится.
Re[7]: С# 3.0
От: stalcer Россия  
Дата: 16.09.05 07:30
Оценка:
Здравствуйте, Кодёнок, Вы писали:

Кё>Людям явно не нравится механизм обработки исключений и они ощут альтернативы


А при чем здесь исключения. null есть только для ссылочных типов. А, например, возмем структуру Address. Пусть адрес может быть не задан по условию задачи. И что? Придется заводить еще и булевый признак? Не зря же в SQL сделали NULL. Да и не только в SQL.
http://www.lmdinnovative.com (LMD Design Pack)
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.