Ошибка приведения типа читателя Npgsql (было: mono плохо сериализует сложные типы)

Прав ли я, что сериализация сложных типов еще не реализована в Mono 2.4.2, или я ошибся?

Когда я вызываю свою удаленную функцию, я получаю сообщение об ошибке:

Cannot cast from source type to destination type.
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke 
    (System.Runtime.Remoting.Proxies.RealProxy rp, IMessage msg,
     System.Exception& exc, System.Object[]& out_args) [0x00000]

Это удаленная функция. Я получил тот же результат, когда вместо этого использовал string[]. string хорошо пробивается.

public List<string> GetHist()
{
    NpgsqlConnection conn = new NpgsqlConnection(ConnectStr);
    conn.Open();

    string cmd = "select * from history";
    NpgsqlCommand command = new NpgsqlCommand(cmd, conn);
    List<string> s = new List<string>();

    try
    {
        NpgsqlDataReader dr = command.ExecuteReader();
        if (dr.Read())
        {
            for (int i = 0; i < dr.FieldCount; i++)
                s.Add(dr.GetString(i));
        }
        else
            s.Add("(hehe)");
    }
    finally
    {
        conn.Close();
    }
    return s;
}

Звонивший:

List<string> w = remoteClass.GetHist();
foreach (string s in w)
    Console.Write(s + ", ");
Console.WriteLine();

Я нашел это на http://mono-project.com/FAQ:_Technical:

Как насчет совместимости с сериализацией? Могу ли я сериализовать объект в Mono и десериализовать его в MS.NET или наоборот?

Формат сериализации, реализованный в Mono, полностью совместим с форматом MS.NET. Однако наличия совместимого формата недостаточно. Для успешного обмена сериализованными объектами соответствующие классы должны иметь одинаковую внутреннюю структуру (то есть одинаковые открытые и закрытые поля) с обеих сторон.

Если вы сериализуете свои собственные классы, проблем нет, поскольку вы контролируете сборки и классы, используемые для сериализации.

Однако, если вы сериализуете объекты из фреймворка, совместимость сериализации не гарантируется, поскольку внутренняя структура этих объектов может отличаться. Эта совместимость даже не гарантируется между разными версиями MS.NET или версиями Mono.

Наша политика заключается в том, чтобы сделать классы фреймворка совместимыми между Mono и MS.NET, однако иногда это невозможно, поскольку внутренняя реализация слишком отличается. Обратите также внимание, что когда мы меняем класс, чтобы сделать его совместимым с MS.NET, мы теряем совместимость со старыми версиями Mono.

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

(Обратите внимание, что это относится только к сериализаторам, основанным на платформе System.Runtime.Serialization, и не относится к XmlSerializer).

Однако он не работает даже между приложением mono-2.4.2 и другим приложением mono-2.4.2.


person Denes Tarjan    schedule 24.07.2009    source источник
comment
Кажется, проблема не в сериализации, а в классе чтения Npgsql, GetString() или чем-то еще.   -  person Denes Tarjan    schedule 24.07.2009


Ответы (2)


Проблема в Npgsql, поэтому я меняю заголовок. Эти две строки должны быть эквивалентны, я думаю, обе должны возвращать string, но первая не работает:

dr.GetString(i)
dr[i].ToString()

Чтобы еще больше усложнить отладку, удаленное взаимодействие .net передало ошибку вызывающей стороне.

person Denes Tarjan    schedule 24.07.2009

Сериализация .net не делает дженерики... пока... гррррр.

Mono может быть сложным, но начиная с .net 2.0 string[] должен работать. Чтобы быть уверенным, попробуйте свой код на окнах.

person Ray    schedule 24.07.2009