Здравствуйте, VladD2, Вы писали:
VD>К тому же за эту гибкость ты вынужден платить снижением произвоидтельности. Скажем вместо операторов (+, -, *, /) ты будешь создавать какие-то классы и перпедавать на них ссылки, что превратит любой числодробильный алгоритм в ленивца.
Ну, если стратегию передавать через дженерик-параметр, то снижения производительности не будет. Т.е. обобщенное числодробление
Здравствуйте, 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>Что такое расширение даст, что потребует, и так далее.
Я считаю, что лучше дать возможность сопоставлять констрейнт любому типу неинтрузивно.
Т.е. как-то так:
public interface COperationable<A> { A Operation(A arg); }
//Foo - класс или структура, которую мы не можем изменить.public type Foo implements COperationable
{
A Operation(A arg)
{
//реализация
}
}
public class TemplateT<A> where A : class COperationable
{
A DoubleOperation(A arg)
{
return arg.Operation().Operation();
}
}
...
var tt = new TemplateT<Foo>();
Т.е. добавить урезанные классы типов, ну или абстрактные интерфейсы из Nice.
Все это разворачивается в:
public interface COperationable<A> { A Operation(A arg); }
[Implementation("Foo", "COperationable")]
public struct Foo_COperationable : COperation<Foo>
{
A Operation(A arg)
{
//реализация
}
}
[Implicit("CT")]
[ClassType("A", "COperationable")]
public class TemplateT<A, CT> where CT : COperationable<A>, new()
{
static CT ct = new CT();
A DoubleOperation(A arg)
{
return ct.Operation(ct.Operation(ct));
}
}
...
//компилятор подставляет второй неявный параметр,
//подбирая соответствующую реализацию для типа Foo из области видимости.var tt = new TemplateT<Foo, Foo_COperationable>();
... << RSDN@Home 1.2.0 alpha 4 rev. 1325>>
'You may call it "nonsense" if you like, but I'VE heard nonsense, compared with which that would be as sensible as a dictionary!' (c) Lewis Carroll
Re[4]: C# - идея расширения для where - новое ограничение дл
K>На этот счет у меня была идея для другого расширения, другго констрэйнта: K>
K>public interface IExecutable
K>{
K> void Execute();
K>}
K>public T Code<T>(T arg) where T simular IExecutable
K>{
K> atg.Execute();
K>}
K>
K>где T реализует IExecutable либо объявляет как минимум то же самое public что и в IExecutable. K>Типа K>
K>public T Code<T>(T arg) where T simular <IntefaceType>
K>
Это хорошая идея, и приходила в голову она не только вам ).
Но думаю воплотить ее не просто.
А вот еще идея. А что если вообще не завязыватся на имена методов? Ну скажем требование к типу-параметру
"тип должен иметь метод A : void A(double x)" заменяем на
"тип должен иметь метод с сигнатурой void [MethodName](double x)". Но тогда генерик не поймет какой из 2х методов одинаковой сигнатуры юзать.
Тут должен появится мапинг методов.
К чему бы это привело на практике — незнаю. Как обычно наверно, в кривых руках эта фича создала бы монстроподобный код.
Re[6]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, samius, Вы писали:
S>Все немного сложнее. Объявления операций сложения/умножения и т.п. в INumber сами по себе мало чем полезны. Даже для того, чтобы посчитать среднее арифметическое от T[] нужно уметь складывать T с типом накопителя (например double) и потом делить тип накопителя на целое (double умеем, но TAgregate в общем случае — нет). Можно складывать T- друг с другом, но в случае byte[] быстро получим переполнение.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, samius, Вы писали:
S>>Все немного сложнее. Объявления операций сложения/умножения и т.п. в INumber сами по себе мало чем полезны. Даже для того, чтобы посчитать среднее арифметическое от T[] нужно уметь складывать T с типом накопителя (например double) и потом делить тип накопителя на целое (double умеем, но TAgregate в общем случае — нет). Можно складывать T- друг с другом, но в случае byte[] быстро получим переполнение.
IT>Всё это уже давно есть в BLToolkit:
IT>Выглядит, конечно, мрачноватенько, но пользоваться вполне можно.
Здорово.
Инлайнится?
Re[8]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, samius, Вы писали:
S>Здравствуйте, IT, Вы писали:
IT>>Выглядит, конечно, мрачноватенько, но пользоваться вполне можно.
S>Здорово. S>Инлайнится?
В отличие от методов generic-типов, generic-методы совсем не инлайнятся, как показывает практика
Re[10]: C# - идея расширения для where - новое ограничение д
Здравствуйте, IT, Вы писали:
IT>Я и не настаиваю Впрочем, для масштабных и обобщённых вообще ничего не подойдёт.
Я как-то делал прототип Bitmap<T> и какую-то операцию над ним (уже не помню) через передачу generic арифметики над типом T. Выжал 98% производительности от необобщенной версии. Получилось громмоздко, потому в команде предпочли множественный copy&paste (число типов T было ограничено, не больше 10и).
Re[5]: C# - идея расширения для where - новое ограничение дл
K>>public T Code<T>(T arg) where T simular <IntefaceType>
K>>
_>Это хорошая идея, и приходила в голову она не только вам ). _>Но думаю воплотить ее не просто.
Есть такая проблема, мда...
Сложность воплощения не в реализации самой проверки а "уговорить добавить сответствующий элемент языка. Особенно если этот элемент применим только для Public — членов, то есть проверяются только они.
_>А вот еще идея. А что если вообще не завязыватся на имена методов? Ну скажем требование к типу-параметру _>"тип должен иметь метод A : void A(double x)" заменяем на _>"тип должен иметь метод с сигнатурой void [MethodName](double x)". Но тогда генерик не поймет какой из 2х методов одинаковой сигнатуры юзать. _>Тут должен появится мапинг методов.
Мапинг методов... это перебор, потому что мапинг дожен быть на чтото — на имена,на Guid-ы операций....
Абсодютно обобщенный объект имеет интерфейс
public object this[object key] { get; set; }
У меня коллега на таком интерфейсе делал объекты, и можно было даже методы вызывать через этот интерфейс.
Re[2]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, Klapaucius, Вы писали:
K>Здравствуйте, 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>>Что такое расширение даст, что потребует, и так далее.
K>Я считаю, что лучше дать возможность сопоставлять констрейнт любому типу неинтрузивно.
K>Т.е. как-то так:
K>
K>public interface COperationable<A> { A Operation(A arg); }
K>//Foo - класс или структура, которую мы не можем изменить.
K>public type Foo implements COperationable
K>{
K> A Operation(A arg)
K> {
K> //реализация
K> }
K>}
K>public class TemplateT<A> where A : class COperationable
K>{
K> A DoubleOperation(A arg)
K> {
K> return arg.Operation().Operation();
K> }
K>}
K>...
K>var tt = new TemplateT<Foo>();
K>
K>Т.е. добавить урезанные классы типов, ну или абстрактные интерфейсы из Nice. K>Все это разворачивается в: K>
K>public interface COperationable<A> { A Operation(A arg); }
K>[Implementation("Foo", "COperationable")]
K>public struct Foo_COperationable : COperation<Foo>
K>{
K> A Operation(A arg)
K> {
K> //реализация
K> }
K>}
K>[Implicit("CT")]
K>[ClassType("A", "COperationable")]
K>public class TemplateT<A, CT> where CT : COperationable<A>, new()
K>{
K> static CT ct = new CT();
K> A DoubleOperation(A arg)
K> {
K> return ct.Operation(ct.Operation(ct));
K> }
K>}
K>...
K>//компилятор подставляет второй неявный параметр,
K>//подбирая соответствующую реализацию для типа Foo из области видимости.
K>var tt = new TemplateT<Foo, Foo_COperationable>();
K>
Маленькое уточнение... было бы неплохо ввести обозначение "здесь будет подобран тип позднее".
public class A<B> where B simular String
{
}
public class A2<Arg> where Arg : A<*>
{
}
Екак-то так но этовсётаки перебор. Вероятность неоднознаности over 9000....
Re[5]: C# - идея расширения для where - новое ограничение дл
Здравствуйте, barn_czn, Вы писали:
_>А вот еще идея. А что если вообще не завязыватся на имена методов? Ну скажем требование к типу-параметру _>"тип должен иметь метод A : void A(double x)" заменяем на _>"тип должен иметь метод с сигнатурой void [MethodName](double x)". Но тогда генерик не поймет какой из 2х методов одинаковой сигнатуры юзать. _>Тут должен появится мапинг методов.
_>К чему бы это привело на практике — незнаю. Как обычно наверно, в кривых руках эта фича создала бы монстроподобный код.
Как к чему? К yet another turing-complete macro language.
С этой точки зрения, эффективнее называть вещи своими именами, и указывать маппинг традиционным способом:
public DuckWrapper: IDuck
{
public DuckWrapper(WildDuck duck) {_duck = duck;}
public IDuck.Quack { _duck.Kryak(); }
}
Можно пойти обратным путём: собирать выражения в виде Expression и компилировать весь цикл математики, выполняя, таким образом, инлайнинг вручную.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: C# - идея расширения для where - новое ограничение дл