class A {}
class B : A {}
module Program
{
public Cat[T](this e1 : IEnumerable[T], e2 : IEnumerable[T]) : IEnumerable[T]
{
foreach (item in e1)
yield item;
foreach (item in e2)
yield item;
}
public Cat[T, U](this e1 : IEnumerable[T], e2 : IEnumerable[U]) : IEnumerable[U]
where T : U
{
foreach (item in e1)
yield item : U;
foreach (item in e2)
yield item;
}
public Cat[T, U](this e1 : IEnumerable[U], e2 : IEnumerable[T]) : IEnumerable[U]
where T : U
{
foreach (item in e1)
yield item;
foreach (item in e2)
yield item : U;
}
Main() : void
{
def a = [A(), A(), A()] : IEnumerable[A];
def b = [B(), B(), B(), B()] : IEnumerable[B];
_ = a.Cat(b);//Вызов метода номер 3
_ = b.Cat(a);//Вызов метода номер 2
_ = a.Cat(a);//Ошибка. Поздходят все три метода.
}
}
Можно ли изменять правила разрешения перегрузки чтобы был выбран первый метод?
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
WH>Можно ли изменять правила разрешения перегрузки чтобы был выбран первый метод?
Это перегрузка по констрэйнма. Ее потенциально можно реализовать, только вот SRE не позвляет задать методв по констрэйну. Точнее это вообще невозможно, но в дотнет поддерижваются специальнае метаданные позволяющие отличать методы. Так вот SRE их спользование недопускает.
Такую фичу можно сделать если портировать немерле на CCI. Но это само по себе не мало работы. Хотя портирвоать однозначно надо. Это решит много проблем.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Это перегрузка по констрэйнма. Ее потенциально можно реализовать, только вот SRE не позвляет задать методв по констрэйну. Точнее это вообще невозможно, но в дотнет поддерижваются специальнае метаданные позволяющие отличать методы. Так вот SRE их спользование недопускает.
Может я что-то не понимаю но вот этот код работает:
def a = [A(), A(), A()] : IEnumerable[A];
def b = [B(), B(), B(), B()] : IEnumerable[B];
def c = [C(), C(), C(), C(), C()] : IEnumerable[C];
def x = b.Cat(a).Cat(c);
WriteLine($"..$x");
Выведет:
B, B, B, B, A, A, A, C, C, C, C, C
Проблемы начинаются когда подсовываешь одинаковые типы.
На код b.Cat(b) компилятор говорит:
Здравствуйте, WolfHound, Вы писали:
WH>Может я что-то не понимаю но вот этот код работает: WH>
WH> def a = [A(), A(), A()] : IEnumerable[A];
WH> def b = [B(), B(), B(), B()] : IEnumerable[B];
WH> def c = [C(), C(), C(), C(), C()] : IEnumerable[C];
WH> def x = b.Cat(a).Cat(c);
WH> WriteLine($"..$x");
WH>
По идее не должен был даже скомпилироваться. Немерл я докрутил для поддержки перегрузки по констрэйнам, а вот SRE должно генерировать фигню. Возможно все же тут имеет дело перегрузка по параметрам типов.
Но в случае одинаковых параметров действительно не ясно какой предпочесть.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>По идее не должен был даже скомпилироваться. Немерл я докрутил для поддержки перегрузки по констрэйнам, а вот SRE должно генерировать фигню. Возможно все же тут имеет дело перегрузка по параметрам типов.
Так оно и есть.
Если у одного из методов поменять метами T и U
Cat[U, T](...)
То компилироваться перестанет.
VD>Но в случае одинаковых параметров действительно не ясно какой предпочесть.
Хотелось бы вот этот
public Cat[T](this e1 : IEnumerable[T], e2 : IEnumerable[T]) : IEnumerable[T]
Ибо у нас тут точное совпадение типов.
... << RSDN@Home 1.2.0 alpha 4 rev. 1305>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Честно говоря, это начинает подозрительно напоминать игру компилятора в "угадайки".
ИМХО не стоит такие вещи делать, если нет желания превратить в Немерле в Вижуал Бейсик.
Здравствуйте, VladD2, Вы писали:
VD>Эх. Пора тебе в дебри вывода типов погрузиться .
VD>Могу показать откуда копать...
Там давно все переписать нужно...
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[6]: Разрешение перегрузки.
От:
Аноним
Дата:
29.04.10 15:16
Оценка:
Здравствуйте, Воронков Василий, Вы писали:
ВВ>Честно говоря, это начинает подозрительно напоминать игру компилятора в "угадайки". ВВ>ИМХО не стоит такие вещи делать, если нет желания превратить в Немерле в Вижуал Бейсик.
На VB-то не наезжайте Там алгоритмы перегрузки такие же как в C#.
Здравствуйте, Аноним, Вы писали:
ВВ>>Честно говоря, это начинает подозрительно напоминать игру компилятора в "угадайки". ВВ>>ИМХО не стоит такие вещи делать, если нет желания превратить в Немерле в Вижуал Бейсик. А>На VB-то не наезжайте Там алгоритмы перегрузки такие же как в C#.
Это просто абсолютная неправда. Алгоритмы перегрузки в VB.NET и C# разные. И отличий там до фига. Взять хотя бы то, что VB учитывает виртуальные функции как first class кандидаты и поддерживает hide by name. Причем многие отличия как раз и сводятся к тому, что C# выдает ошибку при неоднозначности, а VB пытается угадать.
Как там вообще даже теоретически может быть одинаковый overloading, если в VB всегда были optional параметры, а в шарпе только что появились?
Здравствуйте, Аноним, Вы писали:
А>На VB-то не наезжайте Там алгоритмы перегрузки такие же как в C#.
Немного похожие, но не такие же. Я бы сказал, что общей является только идея "выбираем то, что лучше подходит". Считается, что VB.NET чаще пытается "угадать" в случае неоднозначности.
Да и в C# правила для overload resolution не всегда интуитивно понятные.
Можешь попробовать покопаться. Только если вдруг что-то будешь править, не забудь прогнать все тесты и скомпилировать компилятор в многостадийном режиме (короче, прогнать DevBuildForCommit.cmd), потому как сломать что-то там можно за проста.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Можешь попробовать покопаться.
Только учти, что все это потеряет смысл с перходом на 4-ый фрймворк, так как там будет ковариантность для для IEnumerable, так что все заработает само собой.
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Re[5]: Новая фича (надеюсь, последняя) - макрос Resource