Re[23]: Насколько важен синтаксис языка?
От: FDSC Россия consp11.github.io блог
Дата: 08.09.06 10:49
Оценка:
Здравствуйте, Sinclair, Вы писали:

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

Д>>лучще приведи пример кода, где не жить не быть — но без нелокальных возвратов обойтись нельзя
S>Да нет такого кода. Но смысл я понял.
S>Там, где дотнету приходится делать два метода: FindFirst и Apply, смоллток обходится одним. Просто потому, что решение о том, продолжать итерацию или выйти "изо всего" принимается в "делегате".
S>В более сложных случаях давайте вспомним, как мы делали поиск по дереву. Конечно же рекурсия; и конечно же надо было обязательно оборудовать ее проверкой на продолжение и сохранением найденного элемента...
S>Если бы нелокальный возврат существовал бы в дотнете, это работало бы как-то так:
S>
S>public interface IRecursible<T>: IEnumerable<IRecursible<T>>;

S>public static void ForEach<T>(T root, Action<T> action)
S>  where T: IRecursible<T>
S>{
S>  action(root);
S>  foreach(T child in root)
S>      ForEach(child, action);
S>}
S>


S>Это мы так один раз объявили служебный метод. Его можно применять чтобы, например, выводить все дерево:


S>
S>class MyItem: IRecursible<MyItem>
S>{
S>  // тривиальная реализация интерфейса поскипана
S>    public string Name;
S>}

S>public static PrintAll(MyItem root)
S>{
S>  ForEach(root, delegate(MyItem t) { Console.WriteLine(t.Name);});
S>}
S>

S>Тривиально, не правда ли? А теперь давайте кого-нибудь найдем:

S>
S>public static MyItem FindFirstStartingWith(MyTtem root, string start)
S>{
S>  ForEach(root, 
S>        delegate(MyItem t) 
S>        { 
S>            if (t.Name.StartsWith(start))
S>                super return t;
S>        } 
S>    );
S>}
S>

S>Здесь я применил "новый" оператор super return, чтобы намекнуть на нелокальный возврат (в отличие от обычного return, который все равно приведет к ошибке компиляции из-за несовпадения типа получившегося анонимого делегата с Action<MyItem>).
S>На что стоит обратить внимание?

Банально

public static void ForEach<T>(T root, Action<T> action)
where T: IRecursible<T>
{
action(root);
CRT Child = root.LoadFromDataBaseChildAndLock();
foreach(T Child in root)
{

ForEach(Child, action);
}
Child.Unlock();
}
S>[/c#]

и уже ошибка
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.