Классы и интерфейсы в S#
Atom
07.10.2010


Михаил, я начал писать реализацию iTrader для S#, точнее пока только написал вроппер вокруг их библиотеки. И возникли некоторые вопросы по поводу дизайна базовых типов, а именно:
почему Candle абстрактный, почему в itrader передаются не интерфейсы, а классы( например Candle а можно было сделать просто ICandle?). Вопросы эти возникли по следующей причине:
Transaq Connector сделан по-дурацки он обменивается с программой неполноценными xml(зачем они эту ересь сделали не представляю-руки бы поотрывал тому кто это придумал). Поэтому я написал свои типы которые сериализуются и десериализуются. Встал вопрос совместимости с вашими типами. Унаследовать от Ваших классов не могу( мне же нужно сериализовать или десериализовать-а делаю это с помощью атрибутов). Были бы интерфейсы-никаких проблем. Эту проблему я конечно обойду-напишу преобразование типов. Но хочется чтобы пользователь имел доступ к дополнительным данным( ведь коннектор впринципе по некоторым полям передает больше значений). Итого: предлагаю Вам рассмотреть возможность использования только интерфейсов в iTrader. Тогда конкретная реализация зависела бы коннектора и могла учитывать какие-то его особенности или нести доп. поля.

Теги:


Спасибо:


Mikhail Sukhov

Фотография
Дата: 07.10.2010
Ответить


Андрей Ефимов

почему Candle абстрактный,


Потому что это базовый класс. Обычно под счетчками подрузомевают временные. Для них как раз есть проивзодный от Candle класс - TimeFrameCandle.

Андрей Ефимов

почему в itrader передаются не интерфейсы, а классы( например Candle а можно было сделать просто ICandle?).


Там где нет реализации - использую интерфейсы. Там где есть - использую классы.

Андрей Ефимов

Transaq Connector сделан по-дурацки он обменивается с программой неполноценными xml(зачем они эту ересь сделали не представляю-руки бы поотрывал тому кто это придумал).


Товарщини изобрели веб сервис[biggrin]

Андрей Ефимов

Поэтому я написал свои типы которые сериализуются и десериализуются.


Ручками или какой-то спец механизм, аля XmlSerializer?

Андрей Ефимов

Встал вопрос совместимости с вашими типами. Унаследовать от Ваших классов не могу( мне же нужно сериализовать или десериализовать-а делаю это с помощью атрибутов). Были бы интерфейсы-никаких проблем. Эту проблему я конечно обойду-напишу преобразование типов. Но хочется чтобы пользователь имел доступ к дополнительным данным( ведь коннектор впринципе по некоторым полям передает больше значений).


Расскажите по подробнее о механизме сериализации и как это работает в транзаке. Попробую предложить решение.

Андрей Ефимов

Тогда конкретная реализация зависела бы коннектора и могла учитывать какие-то его особенности или нести доп. поля.


Доп поля записываются через ExtensionInfo
Спасибо:

anothar

Фотография
Дата: 07.10.2010
Ответить


Нет, боже упаси это делать ручками. Да через сериалайзер. Только сейчас пришла идея делать через xslt-тогда можно все привести к базовому классу. но уже поздно-код написан, да медленная это вещь. и не говорите- изобрели блин да не тем местом, колеса вдруг стали квадратными. один способо как с этим побороться я знаю-создать новый класс, производный от Вашего и написать в моем классе метод преобразования к этому классу, мне он не нравится тем что мне еще придется плодить классы, может у Вас есть предложение как это реализовать без создания еще новых классов? Тут основная проблема в том, что я не смогу переопределить сериализацию у Ваших типов( ну или это будет весьма геморно), точнее у их полей.
Спасибо:

Mikhail Sukhov

Фотография
Дата: 07.10.2010
Ответить


Андрей Ефимов
Нет, боже упаси это делать ручками. Да через сериалайзер.


Интересно, а что, там названия у нод и атрибутов любые могут быть? Или Вы поля у сущности назвали так же, как принято у Транзака? Если второе, то это не очень хорошо. Я раньше так же начинал с Квиком, делать десериализацию ДДЕ данных сразу в сущности. Потом такие траблы начались ввиде больших переделок на добавление нового поля.

Так что для себя я решил. Создание нового трейдера начинается с тотальной обертки АПИ. И эта обертка никак не использует типы S#. А сам трейдер лишь делает конвертацию данных туда и обратно.

Андрей Ефимов

Тут основная проблема в том, что я не смогу переопределить сериализацию у Ваших типов( ну или это будет весьма геморно), точнее у их полей.


Согласен. Я использую свою сериализацию на основе Ecng.Serialization. Отличается от стандартной тем, что можно контролировать процесс сериализации.
Спасибо:

anothar

Фотография
Дата: 07.10.2010
Ответить


Цитата:
Интересно, а что, там названия у нод и атрибутов любые могут быть?

Название полей и атрибутов можно контролировать с помощью XmlElement/XmlAttribute. нет названия у меня более понятные. Если поле уж совсем корявое то я обычно делаю нормальное поле. кот не сериализую/десериализую и ПолеAsString кот и сериализуется/десериализуется.
Цитата:
Согласен. Я использую свою сериализацию на основе Ecng.Serialization. Отличается от стандартной тем, что можно контролировать процесс сериализации.

А можно поподробней. чем она отличается от стандартной? В стандартной можно контролировать названия полей с помощью атрибутов. На чем основана ваша собственная сериализация/десериализация?
Цитата:
Так что для себя я решил. Создание нового трейдера начинается с тотальной обертки АПИ. И эта обертка никак не использует типы S#.

Если были бы интерфейсы, а не классы то в моем случае можно было бы создать и на основе интерфейсов S#. Впринципе добавить еще одно поле при стандартной десериализации несложно.
Спасибо:

Mikhail Sukhov

Фотография
Дата: 09.10.2010
Ответить


Андрей Ефимов
А можно поподробней. чем она отличается от стандартной? В стандартной можно контролировать названия полей с помощью атрибутов. На чем основана ваша собственная сериализация/десериализация?


На метаданных (атрибуты или xml). Отличается наличием конвертеров. Например, сложные типы (картинки, шифрованные строчки, сетевые адреса) в xml так просто не запихать. Приходится создавать структуру только для сериализации, где такие типы упакованы в примитивный формат (строка, число). Ecng.Serialization использует конвертеры на поля. Он превращает сложный тип в простой при сериализации и наоборот.

И еще одно большое отличие - SerializatonItem. Это древовидная структура, которая содержит данные для записи в файл (или только то прочитанные из). Плюс в том, что эти данные можно потом передавать куда угодно. И записывать как угодно. Со стандартными сериализаторами такое не прокатит.

Пришлите мне какой-нить юз кейс из транзака и как Вы хотите его использовать с типом S#, а я вставлю код для работы через Ecng.Serialization.


Спасибо:

anothar

Фотография
Дата: 09.10.2010
Ответить


Цитата:
На метаданных (атрибуты или xml). Отличается наличием конвертеров. Например, сложные типы (картинки, шифрованные строчки, сетевые адреса) в xml так просто не запихать. Приходится создавать структуру только для сериализации, где такие типы упакованы в примитивный формат (строка, число). Ecng.Serialization использует конвертеры на поля. Он превращает сложный тип в простой при сериализации и наоборот.

Вроде в стандартной сериализации можно реализовать свою сериализацию-то есть переопределить целиком. Но это как-то геморно. Я пробовал и не получилось, так что наверняка утверждать не буду.
Цитата:
И еще одно большое отличие - SerializatonItem. Это древовидная структура, которая содержит данные для записи в файл (или только то прочитанные из). Плюс в том, что эти данные можно потом передавать куда угодно. И записывать как угодно. Со стандартными сериализаторами такое не прокатит.

А это не аналог ли XmlDocument?
Вот пример из моего кода:
Код

[Serializable]
public class ErrorCallback:ServerCallback
{
private static XmlSerializer _serializer = new XmlSerializer(typeof(ErrorCallback));

[XmlElement("error")]
public String Error
{
get;
set;
}

public static ErrorCallback FromXmlString(String s)
{
s = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<ErrorCallback>"+s
+"</ErrorCallback>";
using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(s)))
{
return (ErrorCallback)_serializer.Deserialize(stream);

}
}
}

Пока времени не было чтобы начать реализовать iTrader. Это пример прямо из кода использования стандартной десериализации для callback. для отправки команд я сериализую ручками( для десериализации бы это потребовало очень много времени). Вот пример xml ки которую должна парсить эта функция:
Код

<error>Описание ошибки</error>

Напишите, пожалуйста, пример того как это будет выглядеть при Вашей десериализации.
Спасибо:

Mikhail Sukhov

Фотография
Дата: 12.10.2010
Ответить


1. Стандартная сериализация позволяет контролировать только весь процесс в целом, а не какое-то отдельное поле. Да и реализовать интерфейс IXmlSerializable мягко говоря не для слабонервных.

2.
Код
public class ErrorInfo
{
[Field("error")]
public string Info { get; set; }
}

var ser = new XmlSerializer<ErrorInfo>();
ser.Deserialize(s);


3. Вы в курсе, что атрибут Serializable никаким образом не относится к XmlSerializer?
Спасибо:

anothar

Фотография
Дата: 12.10.2010
Ответить


Спасибо, Михаил.
1. Моих нервов не хватало.
2. Выглядит проще обычной сериализации, потихоньку буду разбираться. Буду в дальнейшем пользоваться Вашей библиотекой, но пока оставлю свой код, ибо негоже просто так переделывать код.
3. Нет. Но после Вашего вопроса вспомнил, что пару раз я это замечал. Я всегда путаюсь с XmlSerializer, BinaryFormatter и SoapFormatter. Почему-то в книгах чаще упоминают последние два[biggrin]
Спасибо:


Добавить файлы через драг-н-дроп, , или вставить из буфера обмена.

loading
clippy