Здравствуйте, Andir, Вы писали:
A>Чем не подходит стандартное требование реализации интерфейса? Зачем дробить ещё на более мелкие функциональные единицы?
A>С Уважением, Andir!
Существуют случаи, когда применить алгоритм к набору объектов класса, к которому у вас нет исходников, чтобы добавить реализацию нужного вам интерфейса. А формально сигнатуры методов есть и они видны в области видимости вашего алгоритма. Что вы в таких случаях бы делали?
Я подозреваю, что писали бы wrapper-ы либо для объектов либо для шагов алгоритма, что усложнило бы итоговый код.
Re: C# - идея расширения для where - новое ограничение для т
Здравствуйте, konstardiy, Вы писали:
K>Существуют случаи, когда применить алгоритм к набору объектов класса, к которому у вас нет исходников, чтобы добавить реализацию нужного вам интерфейса. А формально сигнатуры методов есть и они видны в области видимости вашего алгоритма. Что вы в таких случаях бы делали? K>Я подозреваю, что писали бы wrapper-ы либо для объектов либо для шагов алгоритма, что усложнило бы итоговый код.
wrapper-ы не едиственное решение. можно стратегию вызова метода Operation передавать. выйдет даже гибче.
Re[2]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, nikov, Вы писали:
N>Здравствуйте, konstardiy, Вы писали:
K>>Предлагаю осудить, кому интересно.
Изобрели Type Classes практически
K>>Что такое расширение даст, что потребует, и так далее.
Если уж делать для всех языков, то потребуется серьёзное изменение рантайма...
N>Предлагаю взглянуть на F# 1.9.7 Specification, 5.1.5.3 Member Constraints
Здравствуйте, Lloyd, Вы писали:
L>wrapper-ы не едиственное решение. можно стратегию вызова метода Operation передавать. выйдет даже гибче.
Интересно.. Передавать в сумматор стратегию сложения.. Это даже немного забавно...
Если бы в c# был базовый класс Number или возможность объявить в интерфейсе перегрузку оператора и соответственно интерфейс INumber, половина потребности в has испарилась бы в стратосферу.
Re: C# - идея расширения для where - новое ограничение для т
Здравствуйте, konstardiy, Вы писали:
K>Вот простой пример: K>
K> public class TemplateT<A> where A has { A Operation(); }
K> {
K> A DoubleOperation(A arg)
K> {
K> return arg.Operation().Operation();
K> }
K> }
K>
K>Предлагаю осудить, кому интересно. K>Что такое расширение даст, что потребует, и так далее.
Что там обсуждать? Это называется "концепты". Планировалось добавить к C++0x, но было выбрашено в виду того, что комитету не хватало времени на пьянки.
Проблема в том, что этот подход подразумевает утиную типизацию которая не поддерживается напрямую в дотнете (в рантайме). Некоторая эмуляция есть в F#.
Собственно что уж тогда останавливаться? Тогда уж можно было бы описывать операторы и статические функции. Вот только это еще хуже вяжется с подходами используемыми в рантайме дотнета.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[2]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, Andir, Вы писали:
A>Чем не подходит стандартное требование реализации интерфейса?
Тем что оно прибивает гвоздями к необходимости реализации этих интерфейсов в классах. А что делать если класс не твой, он sealed или struct?
A>Зачем дробить ещё на более мелкие функциональные единицы?
Чтобы иметь большую гибкость.
Собственно описывать отдельные "операции" (точнее функции) не обязательно. Можно было бы ввести поддержку утиной типизации для интерфейсов (как в гуглевском Гоу). Но это нужно реализовывать не в шарпе, а в дотнете, а уже потом во всех языках донета.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[4]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, Lloyd, Вы писали:
L>wrapper-ы не едиственное решение. можно стратегию вызова метода Operation передавать. выйдет даже гибче.
Это и есть обертки. Гикость там где она не нужна — это кривость.
К тому же за эту гибкость ты вынужден платить снижением произвоидтельности. Скажем вместо операторов (+, -, *, /) ты будешь создавать какие-то классы и перпедавать на них ссылки, что превратит любой числодробильный алгоритм в ленивца.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, konstardiy, Вы писали:
L>>wrapper-ы не едиственное решение. можно стратегию вызова метода Operation передавать. выйдет даже гибче.
K>Интересно.. Передавать в сумматор стратегию сложения.. Это даже немного забавно...
Сумматор — это частный случай fold-а, который уже есть в .Net-е (Enumerable.Aggregate)
Re[5]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, konstardiy, Вы писали:
K>Здравствуйте, Lloyd, Вы писали:
L>>wrapper-ы не едиственное решение. можно стратегию вызова метода Operation передавать. выйдет даже гибче.
K>Интересно.. Передавать в сумматор стратегию сложения.. Это даже немного забавно... K>Если бы в c# был базовый класс Number или возможность объявить в интерфейсе перегрузку оператора и соответственно интерфейс INumber, половина потребности в has испарилась бы в стратосферу.
Кстати, если был бы интерфейс IArithmetical и примитивные типы реализовывали бы его методы, то можно было бы писать обобщённые алгоритмы даже устранив вызовы через интерфейс:
public T Square(T value) where T : IArithmetical
{
return value * value;
}
Здравствуйте, konstardiy, Вы писали:
K>Здравствуйте, Lloyd, Вы писали:
L>>wrapper-ы не едиственное решение. можно стратегию вызова метода Operation передавать. выйдет даже гибче.
K>Интересно.. Передавать в сумматор стратегию сложения.. Это даже немного забавно...
Это даже так же быстро как и просто складывать, за счет инлайнинга. Но все-же пользоваться этим неудобно.
K>Если бы в c# был базовый класс Number или возможность объявить в интерфейсе перегрузку оператора и соответственно интерфейс INumber, половина потребности в has испарилась бы в стратосферу.
Все немного сложнее. Объявления операций сложения/умножения и т.п. в INumber сами по себе мало чем полезны. Даже для того, чтобы посчитать среднее арифметическое от T[] нужно уметь складывать T с типом накопителя (например double) и потом делить тип накопителя на целое (double умеем, но TAgregate в общем случае — нет). Можно складывать T- друг с другом, но в случае byte[] быстро получим переполнение.
Потому приходится все приведения, которые умеет делать компилятор (явно или неявно), уметь описывать с помощью констрейнтов, и передавать соответствующие стратегии, в которых должы быть не только способы сложения и умножения T с T, но и приведения типа T ко всему остальному.
В итоге для выполнения обобщенного вычисления среднего арифметического в double вектора int[], придется написать довольно много кода. В разы больше, чем у необобщенного варианта.
Что говорить, если мы захотим реализовать обобщенные фильтры для Bitmap<T>?!?!
Re[5]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, VladD2, Вы писали:
L>>wrapper-ы не едиственное решение. можно стратегию вызова метода Operation передавать. выйдет даже гибче.
VD>Это и есть обертки. Гикость там где она не нужна — это кривость.
Для меня "обертка" — это адаптер. Отличия от стратегии все-таки имеются.
VD>К тому же за эту гибкость ты вынужден платить снижением произвоидтельности. Скажем вместо операторов (+, -, *, /) ты будешь создавать какие-то классы и перпедавать на них ссылки, что превратит любой числодробильный алгоритм в ленивца.
Есть такое.
Re[3]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Andir, Вы писали:
A>>Чем не подходит стандартное требование реализации интерфейса?
VD>Тем что оно прибивает гвоздями к необходимости реализации этих интерфейсов в классах. А что делать если класс не твой, он sealed или struct?
A>>Зачем дробить ещё на более мелкие функциональные единицы?
VD>Чтобы иметь большую гибкость.
VD>Собственно описывать отдельные "операции" (точнее функции) не обязательно. Можно было бы ввести поддержку утиной типизации для интерфейсов (как в гуглевском Гоу). Но это нужно реализовывать не в шарпе, а в дотнете, а уже потом во всех языках донета.
На этот счет у меня была идея для другого расширения, другго констрэйнта:
public interface IExecutable
{
void Execute();
}
public T Code<T>(T arg) where T simular IExecutable
{
atg.Execute();
}
где T реализует IExecutable либо объявляет как минимум то же самое public что и в IExecutable.
Типа
public T Code<T>(T arg) where T simular <IntefaceType>
Re[6]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, Пельмешко, Вы писали:
П>Кстати, если был бы интерфейс IArithmetical и примитивные типы реализовывали бы его методы, то можно было бы писать обобщённые алгоритмы даже устранив вызовы через интерфейс:
П>
П>public T Square(T value) where T : IArithmetical
П>{
П> return value * value;
П>}
П>
S>Все немного сложнее. Объявления операций сложения/умножения и т.п. в INumber сами по себе мало чем полезны. Даже для того, чтобы посчитать среднее арифметическое от T[] нужно уметь складывать T с типом накопителя (например double) и потом делить тип накопителя на целое (double умеем, но TAgregate в общем случае — нет). Можно складывать T- друг с другом, но в случае byte[] быстро получим переполнение. S>Потому приходится все приведения, которые умеет делать компилятор (явно или неявно), уметь описывать с помощью констрейнтов, и передавать соответствующие стратегии, в которых должы быть не только способы сложения и умножения T с T, но и приведения типа T ко всему остальному.
S>В итоге для выполнения обобщенного вычисления среднего арифметического в double вектора int[], придется написать довольно много кода. В разы больше, чем у необобщенного варианта.
S>Что говорить, если мы захотим реализовать обобщенные фильтры для Bitmap<T>?!?!
Смотря что он фильтрует — отдельные экщемпляры T или Bitnap<T> в целом. Вот во втором случае
public abstract FilterBase<T, ValueT> where T has { ValueT R { get; set; } ValueT G { get; set; } ValueT B { get; set; } ValueT A { get; set; }
//simular IPixelData<ValueT>
{
public Bitmap<T> Context { get; private set; }
public abstract double ApplianceStrength(T pixel, int x, int y);
public abstract T Apply(T pixrl, int X, int Y);
public virtual void Apply()
{
foreach(PixelCoordInfo<T> p in Context.EnumerateAllPixels())
{
Context[p.x, p.y] = Aply(p.Pixel, p.X, p.Y);
}
}
}
Пробемы начинаются если мы не знаем точно, что это за ValueT. Их конечно можно решить по другоому, но у has или simular (см в другой ветке) наверно есть какето преимущества?
Re[5]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, Пельмешко, Вы писали:
П>А в чём разница от первого поста кроме взятия перечисления методов из интерфейса?
В снижении количества копипасты в тех случаях, когда тебе нужны все методы интерфейса.
Has нужен если опрация мало или если не хочешь ссылаться на сборку с интерфейсом. Чтобы указать simular — ограничение, нужно ведь сослаться на сборку где объявлен интерфейс...
Re[7]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, konstardiy, Вы писали:
K>Здравствуйте, samius, Вы писали:
S>>Все немного сложнее. Объявления операций сложения/умножения и т.п. в INumber сами по себе мало чем полезны. Даже для того, чтобы посчитать среднее арифметическое от T[] нужно уметь складывать T с типом накопителя (например double) и потом делить тип накопителя на целое (double умеем, но TAgregate в общем случае — нет). Можно складывать T- друг с другом, но в случае byte[] быстро получим переполнение. S>>Потому приходится все приведения, которые умеет делать компилятор (явно или неявно), уметь описывать с помощью констрейнтов, и передавать соответствующие стратегии, в которых должы быть не только способы сложения и умножения T с T, но и приведения типа T ко всему остальному.
S>>В итоге для выполнения обобщенного вычисления среднего арифметического в double вектора int[], придется написать довольно много кода. В разы больше, чем у необобщенного варианта.
S>>Что говорить, если мы захотим реализовать обобщенные фильтры для Bitmap<T>?!?!
K>Смотря что он фильтрует — отдельные экщемпляры T или Bitnap<T> в целом. Вот во втором случае
Я имел в виду convolution filter-ы K>
K>public abstract FilterBase<T, ValueT> where T has { ValueT R { get; set; } ValueT G { get; set; } ValueT B { get; set; } ValueT A { get; set; }
K>
не очень удачный подход, т.к. не все растры 4-х компонентны. Есть монохромные, indexed, colored и т.п.
K>Пробемы начинаются если мы не знаем точно, что это за ValueT.
даже если мы знаем что T это точно byte или точно float, то проблем не избежать. Поинт не в том, чтобы определить абстрактный Apply и реализовывать его для каждого класса T, а в том, чтобы реализовать Apply для некого алгоритма обобщенно лишь однажды и применить его к частным типам.
K>Их конечно можно решить по другоому, но у has или simular (см в другой ветке) наверно есть какето преимущества?
Никаких преимуществ нет. Чтобы убедиться, стоит прикинуть gaussian blur над Bitmap<byte> и Bitmap<System.Drawing.Color>.