Здравствуйте, FDSC, Вы писали:
P>>b. массив данных по прежнему может быть разных типов, главное есть итератор do: , принимающий лямбду.
FDS>Ерунда, это без разницы, если все типы поддерживают один и тот же интерфейс. Это сделать не сложно. Другое дело, что придётся писать небольшой класс-обёртку (один) для стандартных типов, что бы они то же поддерживали этот интерфейс.
Смолток язык динамически типизированный, да еще в добавок с утиной типизацией. Так что положить то массив можно и обработать можно, но вот надежность у такого кода будет ниже плинтуса потому как до выполнения даже бог не сможет предскзать смогут ли объекты обработоать посылаемые им сообщения (взов методов). Ты же смотришь с позиции языков со статической типизацией. В общем-то и в C# можно положить все что угодно приведя это дело к object. Но вот с обработкой действительно будут проблемы. Прийдется или проверять типы динамически, например:
void Do(object obj)
{
IMyInterface myInf = obj as IMyInterface;
if (myInf != null)
{
ЧтоТоДелаем(myInf);
return;
}
string str = obj as string;
if (myInf != null)
{
ДелаемЧтоТоДругое(str);
return;
}
if (obj is int)
ДелаемЧтоТоСовсемДругое(str);
}
или дергать методы через рефлексию.
Первый способ в C# не удобен и не уневерсален, второй — медленнен.
В Немерле, кстати, первый случай реализуется довольно удобно:
void Do(object obj)
{
| myInf is IMyInterface => ЧтоТоДелаем(myInf);
| str is string => ДелаемЧтоТоДругое(str);
| obj is int => ДелаемЧтоТоСовсемДругое(str);
| _ => () // ничепго не делаем.
}
P>>c. условие проверки такое: все хорошо если в массиве есть 2 смежных элемента , из которых второй равен первый*2. Обращаю внимание что типы чисел в массиве данных разные.
FDS>Без проблем, если есть интерфейсы. Просто без проблем...
Да без проблем и без интерфейсов. Например, следующий код берет массив и умножает его элементы на два без учета конкретного типа.
using System;
using System.Console;
using Nemerle.Utility;
def ary = array[2 : object, 1.2F, 2.3D, "5"];
// Map() конвертирует (отображает) один массив в другой преобразуя элементы с
// помощью переданной ему функции (в данном примере лямбды).
def lst = ary.Map(elem => Convert.ToDouble(elem) * 2.0);
WriteLine(lst.ToString(", "));
Вот только одна проблема. Надежность такого кода зависит от ветра в поле. Достоточно поместить в массив хотя бы один элемент не конвертируемый в double и привет.
Например:
using System;
using System.Console;
using Nemerle.Utility;
// По умолчанию Немерле считает смешивание разных отипов в коллекциях ошибкой.
// Чтобы подсказать тип элементов мы уточняем тип первого из них.
// Далее Немерле сам догадывается, что все остальные типы нужно привести к object.
// Таким образом мы получаем массив object-ов хранящий ссылки на объекты разных типов.
def ary = array[2 : object, 1.2F, 2.3D, "x5"];
def lst = ary.Map(elem => Convert.ToDouble(elem) * 2.0);
WriteLine(lst.ToString(", "));
приведет к ислючению в рантайме потому как х5 не преобразуется в double.
Собственно этим и отличается динамический язык от статического. С одной стороны чуть проще, так как подобные хаки не требуют специальных вызовов вроде Convert.ToDouble(elem) (все приводится автоматом), но с другой постоянно можно получить рантайм-ошибку. Это приводит к юнит тестированию на каждый чих и т.п.
... << RSDN@Home 1.2.0 alpha rev. 637>>