Npgsql 读取器类型转换错误(是:mono 不能很好地序列化复杂类型)

发布于 2024-07-27 22:58:53 字数 2335 浏览 6 评论 0原文

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。

总而言之,如果您正在设计一个 将在不同的环境中运行的应用程序 环境和平台 不在你的控制之下,并且需要 共享序列化对象(或者 使用远程处理、纯文件或 无论如何),你必须小心 您分享和避免哪些物品 框架中的对象时 有可能。

(请注意,这仅适用于 基于序列化器 系统.运行时.序列化 框架,并且不适用于 XmlSerializer)。

但是,它甚至无法在 mono-2.4.2 和另一个 mono-2.4.2 应用程序之间工作。

Am I right that serializing complex types is not implemented in Mono 2.4.2 yet, or have I made a mistake?

When I call my remote function, I get an error message:

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]

This is the remote function.
I got the same result when I use string[] instead.
string makes its way through well.

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;
}

The caller:

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

I found this at http://mono-project.com/FAQ:_Technical :

What about serialization compatibility? Can I serialize an
object in Mono and deserialize it in
MS.NET or vice versa?

The serialization format implemented
in Mono is fully compatible with that
of MS.NET. However, having a
compatible format is not enough. In
order to successfully exchange
serialized objects, the corresponding
classes need to have the same internal
structure (that is, the same public
and private fields) in both sides.

If you are serializing your own
classes, there is no problem, since
you have control over the assemblies
and classes being used for
serialization.

However, if you are serializing
objects from the framework,
serialization compatibility is not
guaranteed, since the internal
structure of those objects may be
different. This compatibility is not
even guaranteed between different
MS.NET versions or Mono versions.

Our policy is to do our best to make
the framework classes compatible
between Mono and MS.NET, however
sometimes this is not possible because
the internal implementation is too
different. Notice also that when we
change a class to make it compatible
with MS.NET, we lose compatibility
with older versions of Mono.

In summary, if you are designing an
application that will run in different
environments and platforms which are
not under your control, and which need
to share serialized objects (either
using remoting, plain files, or
whatever), you must be careful with
what objects you share, and avoid
objects from the framework when
possible.

(Notice that this only applies to
serializers based on the
System.Runtime.Serialization
framework, and does not apply to the
XmlSerializer).

However, it does not even work between mono-2.4.2 and another mono-2.4.2 application.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情痴 2024-08-03 22:58:56

.net 序列化不做泛型...但是...grrrrr。

Mono 可能很棘手,但从 .net 2.0 开始,string[] 应该可以工作。 可以肯定的是,请在 Windows 上尝试您的代码。

.net serialization does not do generics...yet...grrrrr.

Mono can be tricky but as of .net 2.0, string[] should work. To be sure, try your code on windows.

流年里的时光 2024-08-03 22:58:55

问题出在 Npgsql 中,所以我更改了标题。
我认为这两行应该是等效的,都应该返回一个字符串,但第一行不起作用:

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

为了使调试更加困难,.net 远程处理将错误传递给调用方。

The problem is in Npgsql so I change the title.
These two lines should be equivalent I think, both should return a string but the first one does not work:

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

To make debugging even harder, .net remoting passed the error to the caller side.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文