C# 4.0 Type Inference
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.09.09 11:35
Оценка: 70 (9)
В C# 4.0 наконец-то появился вывод типов из аргументов, которые сами являются method groups. Это позволяет писать всякие хитрые комбинации generic методов, нигде явно не указывая типов-аргументов.

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        var y = new List<int> {1, 2, 3};
        var z = y.ConvertAll(ConvertToString);
    }

    static string ConvertToString<T>(T x)
    {
        return x.ToString();
    }

    static string ConvertToString(Guid x)
    {
        return x.ToString("N");
    }
}
Re: C# 4.0 Type Inference
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.09.09 13:01
Оценка: 1 (1) +3
Здравствуйте, nikov, Вы писали:

N>В C# 4.0 наконец-то появился вывод типов из аргументов, которые сами являются method groups. Это позволяет писать всякие хитрые комбинации generic методов, нигде явно не указывая типов-аргументов.


А что они вывод типов для конструкторов то не сделают?
Кривотень ведь еще та.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: C# 4.0 Type Inference
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.09.09 13:31
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>А что они вывод типов для конструкторов то не сделают?

VD>Кривотень ведь еще та.

Увы. Даже не слышал, чтобы такое планировалось.
Re: C# 4.0 Type Inference
От: Алексей.  
Дата: 02.09.09 13:51
Оценка:
Здравствуйте, nikov, Вы писали:

N>В C# 4.0 наконец-то появился вывод типов из аргументов, которые сами являются method groups. Это позволяет писать всякие хитрые комбинации generic методов, нигде явно не указывая типов-аргументов.


Где можно прочитать описание как это работает/должно работать?

Раньше компилятор не позволял такого https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=299065
Re: C# 4.0 Type Inference
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.09.09 13:54
Оценка:
Кстати, есть еще одно интересное изменение в спецификации насчет Fixing'а.

Новый вариант:

• We then examine each bound for Xi in turn: For each exact bound U of Xi all types Uj which are not identical to U are removed from the candidate set. For each lower bound U of Xi all types Uj to which there is not an implicit conversion from U are removed from the candidate set. For each upper bound U of Xi all types Uj from which there is not an implicit conversion to U are removed from the candidate set.


Заметьте, что здесь говорится о необходимости implicit conversion, в то время как старый вариант говорил о standard implicit conversion (более узкое множество). На самом деле компилятор и в предыдущей версии работал, как будто речь идет обо всех implicit conversion — разработчики компилятора забыли передать нужный флаг, а я заметил это уже после релиза. Теперь решили привести спецификацию в согласованное состояние с реализацией.
Re[2]: C# 4.0 Type Inference
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.09.09 14:04
Оценка: 4 (1)
Здравствуйте, Алексей., Вы писали:

А>Где можно прочитать описание как это работает/должно работать?

А>Раньше компилятор не позволял такого https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=299065

На самом деле сейчас всё сделали, как и было написано в разделе 7.4.2.6 Output type inferences ещё в спецификации C# 3.0. Overload resolution вполне можно произвести, когда все типы аргументов заданы изначально или выведены ранее. То, что написано на коннекте выглядит просто как не очень серьёзное оправдание.
Re[3]: C# 4.0 Type Inference
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.09.09 14:57
Оценка:
Здравствуйте, nikov, Вы писали:

VD>>А что они вывод типов для конструкторов то не сделают?

VD>>Кривотень ведь еще та.

N>Увы. Даже не слышал, чтобы такое планировалось.


Я тоже. Вообще, не ясно, они там совсем от народа оторвались? Ведь принципиальных проблем с эти не должно быть. Их не не полноценный вывод типов просят сделать, а практически то, что уже есть. Ведь фабричные методы выводятся на раз.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: C# 4.0 Type Inference
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.09.09 15:08
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Их не не полноценный вывод типов просят сделать, а практически то, что уже есть.


Ну не совсем то. Классы можно перегружать по количеству типов-параметров. Если мы позволим опускать типы-аргументы при выводе, то множество конструкторов-кандидатов придется собирать из разных, никак не связанных, типов.

Возникает и много других вопросов. А если конструктор вызван с object/collection initializer (как List в моем примере), то учитывать ли типы выражений в этом инициализаторе для вывода типов-аргументов создаваемого класса? А ведь это могут быть аргументы для нескольких разных методов Add, которые в свою очередь могут быть generic. А учитывать ли иницициализаторы для вложенных объектов? И т.д. и т.п. В общем, нетривиальная задача.
Re[5]: C# 4.0 Type Inference
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.09.09 15:18
Оценка:
Здравствуйте, nikov, Вы писали:

N>Ну не совсем то. Классы можно перегружать по количеству типов-параметров. Если мы позволим опускать типы-аргументы при выводе, то множество конструкторов-кандидатов придется собирать из разных, никак не связанных, типов.


N>Возникает и много других вопросов. А если конструктор вызван с object/collection initializer (как List в моем примере), то учитывать ли типы выражений в этом инициализаторе для вывода типов-аргументов создаваемого класса? А ведь это могут быть аргументы для нескольких разных методов Add, которые в свою очередь могут быть generic. А учитывать ли иницициализаторы для вложенных объектов? И т.д. и т.п. В общем, нетривиальная задача.


Вопрос возникают только у тех, кто хочет найти отговорки для того чтобы ничего не делать.
А на практике, в случаях неоднозначности можно выдавать сообщения об ошибках. А 99% кода будет работать как надо.

Еще раз повторюсь, что раз фабричные методы прокатывают, то и конструктор можно рассматривать как такой фабричный метод.

Погляди на кортежи из .NET 4.0. Методы Create() — это же форменные костыли.
Я бы со стыда сгорел от такой халтуры.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: C# 4.0 Type Inference
От: nikov США http://www.linkedin.com/in/nikov
Дата: 02.09.09 15:26
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Вопрос возникают только у тех, кто хочет найти отговорки для того чтобы ничего не делать.

VD>А на практике, в случаях неоднозначности можно выдавать сообщения об ошибках. А 99% кода будет работать как надо.

Да я, в общем-то, не возражаю. Пусть сделают.
А когда в Nemerle появится вывод сигнатуры для приватных методов класса? А то всё пишет, что not yet implemented, мол.
Re[5]: C# 4.0 Type Inference
От: Пельмешко Россия blog
Дата: 02.09.09 15:53
Оценка: 12 (1)
Здравствуйте, nikov, Вы писали:

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


VD>>Их не не полноценный вывод типов просят сделать, а практически то, что уже есть.


N>Ну не совсем то. Классы можно перегружать по количеству типов-параметров. Если мы позволим опускать типы-аргументы при выводе, то множество конструкторов-кандидатов придется собирать из разных, никак не связанных, типов.


Этого ни в коем случае допускать нельзя, можно же просто ввести синтаксис для различия generic overloads:
var dict = new Dictionary<,> {
    { 1, "abc" },
    { 2, "def" }
};
Другое дело в том, насколько это будет непонятно
Получается что "Dictionary<,>" будет иметь сильно разный смысл в зависимости от контекста: в typeof() и new expression...

N>Возникает и много других вопросов. А если конструктор вызван с object/collection initializer (как List в моем примере), то учитывать ли типы выражений в этом инициализаторе для вывода типов-аргументов создаваемого класса? А ведь это могут быть аргументы для нескольких разных методов Add, которые в свою очередь могут быть generic. А учитывать ли иницициализаторы для вложенных объектов? И т.д. и т.п. В общем, нетривиальная задача.


А вот это пипец..
Re[7]: C# 4.0 Type Inference
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.09.09 16:34
Оценка: :)
Здравствуйте, nikov, Вы писали:

N>Да я, в общем-то, не возражаю. Пусть сделают.

N>А когда в Nemerle появится вывод сигнатуры для приватных методов класса? А то всё пишет, что not yet implemented, мол.

Это сильно усложнит работу интеграции. Если не ошибаюсь, в одном из комитов я поправил предупреждение.
Вывод будет доступен только для параметров имеющих значения по умолчанию.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: C# 4.0 Type Inference
От: VladD2 Российская Империя www.nemerle.org
Дата: 02.09.09 16:38
Оценка:
Здравствуйте, Пельмешко, Вы писали:

N>>Ну не совсем то. Классы можно перегружать по количеству типов-параметров. Если мы позволим опускать типы-аргументы при выводе, то множество конструкторов-кандидатов придется собирать из разных, никак не связанных, типов.


П>Этого ни в коем случае допускать нельзя, можно же просто ввести синтаксис для различия generic overloads:

П>
П>var dict = new Dictionary<,> {
П>    { 1, "abc" },
П>    { 2, "def" }
П>};
П>
Другое дело в том, насколько это будет непонятно

П>Получается что "Dictionary<,>" будет иметь сильно разный смысл в зависимости от контекста: в typeof() и new expression...

Не нужно ничего подобного делать. Если параметры типа не выводятся по простому, то можно просто попросить программиста задать их явно.

В прочем, приведенный пример — это вывод типов из использования, так как данный синтаксис переписывается в присвоение свойств или полей. Но и тут в МС могли бы просто захардкодить этот солучай.

N>>Возникает и много других вопросов. А если конструктор вызван с object/collection initializer (как List в моем примере), то учитывать ли типы выражений в этом инициализаторе для вывода типов-аргументов создаваемого класса? А ведь это могут быть аргументы для нескольких разных методов Add, которые в свою очередь могут быть generic. А учитывать ли иницициализаторы для вложенных объектов? И т.д. и т.п. В общем, нетривиальная задача.


П>А вот это пипец..


Если алгоритм вывода типов грамотный, то все будет ОК. Для шарпа можно тупо ругаться на не однозначные (с его точки зрения) случаи.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[7]: C# 4.0 Type Inference
От: Пельмешко Россия blog
Дата: 02.09.09 18:14
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Здравствуйте, Пельмешко, Вы писали:


N>>>Ну не совсем то. Классы можно перегружать по количеству типов-параметров. Если мы позволим опускать типы-аргументы при выводе, то множество конструкторов-кандидатов придется собирать из разных, никак не связанных, типов.


П>>Этого ни в коем случае допускать нельзя, можно же просто ввести синтаксис для различия generic overloads:

П>>
П>>var dict = new Dictionary<,> {
П>>    { 1, "abc" },
П>>    { 2, "def" }
П>>};
П>>
Другое дело в том, насколько это будет непонятно

П>>Получается что "Dictionary<,>" будет иметь сильно разный смысл в зависимости от контекста: в typeof() и new expression...

VD>Не нужно ничего подобного делать. Если параметры типа не выводятся по простому, то можно просто попросить программиста задать их явно.


Интересно, почему тогда в F# приходится использовать placeholder чтобы руками указать, что создавать будем?
let foo =
    let d = new Dictionary<_,_>()
    d.Add(1, "abc")
    d.Add(2, "def")
    d

Мне всё же кажется, что это неспроста
Re[8]: C# 4.0 Type Inference
От: VladD2 Российская Империя www.nemerle.org
Дата: 03.09.09 14:05
Оценка: 14 (2)
Здравствуйте, Пельмешко, Вы писали:

П>Интересно, почему тогда в F# приходится использовать placeholder чтобы руками указать, что создавать будем?

П>
П>let foo =
П>    let d = new Dictionary<_,_>()
П>    d.Add(1, "abc")
П>    d.Add(2, "def")
П>    d
П>

П>Мне всё же кажется, что это неспроста

Я не уверен, что ты вообще прав. Но если это так, то это вопрос к его разработчику и тем кто хочет протолкнуть в массы такой язык. В Nemerle никакихъ проблем с этим нет:
using System.Collections.Generic;
using System.Console;

module Program
{
  Main() : void
  {
    def d = Dictionary();

    d.Add(1, "abc");
    d.Add(2, "def");

    foreach (x in d)
      WriteLine($"$(x.Key)=$(x.Value)");
  }
}

Более того работает автодополнение при воводе, хинты и т.п. (в IDE).

Вот если будут неоднозначности, то надо будет или плэйсхолдеры задать (как в F#-примере) или даже реальные типы. В прочем, вероятность того, что такая неоднозночность возникнет, на практике, весьма мала. Так что это не более чем теоритические рассуждения цель которых отмазаться от сложной работы.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[9]: C# 4.0 Type Inference
От: Пельмешко Россия blog
Дата: 04.09.09 11:12
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Я не уверен, что ты вообще прав.


Да я сам не уверен, просто поглядел как с этим в других языках

Влад, я вот с нескольких попыток так и не смог заставить немерль создать всё же generic-версию Foo:
class Foo
{
  public this(a : int) { }
}

class Foo[T]
{
  public this(a : T) { }
}

module Program
{
  Main() : void
  {
    def x = Foo(5);
  }
}


Я думал, что должно быть что-то типа:
    def x = Foo(5) : Foo[int];

Но компилятор не разделяет моего мнения
Re[10]: C# 4.0 Type Inference
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.09.09 13:16
Оценка:
Здравствуйте, Пельмешко, Вы писали:

П>Влад, я вот с нескольких попыток так и не смог заставить немерль создать всё же generic-версию Foo:

П>
П>class Foo
П>{
П>  public this(a : int) { }
П>}

П>class Foo[T]
П>{
П>  public this(a : T) { }
П>}

П>module Program
П>{
П>  Main() : void
П>  {
П>    def x = Foo(5);
П>  }
П>}
П>


Вот это как раз конфликт в котором требеуется явно указать аргументы типа:
def x = Foo.[int](5);

Или так:
def x = Foo.[_](5);

так как типы отличаются по количеству параметров типа.

Но на практике такого я не встречал. Типы создаются для конкретных нужд и эти нужды сами определяют разичия между ними.

Что же касается конфликтов, то их хватает и в C#. Замени типы на дженерик-методы и получишь ту же картину.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[11]: C# 4.0 Type Inference
От: _FRED_ Черногория
Дата: 04.09.09 13:54
Оценка:
Здравствуйте, VladD2, Вы писали:

VD>Но на практике такого я не встречал. Типы создаются для конкретных нужд и эти нужды сами определяют разичия между ними.


Например, таплы обычно различают по количеству элементов. Можно, конечно же количество добавляь к имени класса Tuple2<,>; Tuple3<,,> но просто Tuple<,>; Tuple<,,> ИМХО, эстетичнее.
Help will always be given at Hogwarts to those who ask for it.
Re[12]: C# 4.0 Type Inference
От: VladD2 Российская Империя www.nemerle.org
Дата: 04.09.09 14:08
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Например, таплы обычно различают по количеству элементов. Можно, конечно же количество добавляь к имени класса Tuple2<,>; Tuple3<,,> но просто Tuple<,>; Tuple<,,> ИМХО, эстетичнее.


С кортежами никогда никаких проблем не было. У них разные списки параметров типов. В примере приведенно выше было намеренно смоделирована ситуация когда есть два типа конфликтующих при выводе (с типом и такой же без него). У кортежей же всегда разное количество параметров типов которые всегда определяются конструктором.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[13]: C# 4.0 Type Inference
От: _FRED_ Черногория
Дата: 04.09.09 14:19
Оценка:
Здравствуйте, VladD2, Вы писали:

_FR>>Например, таплы обычно различают по количеству элементов. Можно, конечно же количество добавляь к имени класса Tuple2<,>; Tuple3<,,> но просто Tuple<,>; Tuple<,,> ИМХО, эстетичнее.


VD>С кортежами никогда никаких проблем не было. У них разные списки параметров типов. В примере приведенно выше было намеренно смоделирована ситуация когда есть два типа конфликтующих при выводе (с типом и такой же без него). У кортежей же всегда разное количество параметров типов которые всегда определяются конструктором.


Ах да, точно

На самом деле оригинальный вариант так же не редкость (по аналогии с дженерик-методами и методами с тем же именем, но без дженерик-аргументов), но в шарпе это не причиняет неудобств, пока нет вывода типа в вызове конструктора.
Help will always be given at Hogwarts to those who ask for it.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.