SerializationSurrogate Arrays问题 [英] SerializationSurrogate problem with Arrays

查看:64
本文介绍了SerializationSurrogate Arrays问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以帮助我并告诉我为什么以下代码不是

工作,并希望如何让它工作?


我是什么试图做的是制作一个序列化代理商,其中包括
等等,以及由同一个代理商串行化的对象数组。序列化没问题,但是当谈到

反序列化时,数组的数组(正确长度)为
nulls。 grrr ...我正拉着我的头发!!


任何帮助都非常感激。


干杯

Greg


------代码从这里开始------

使用系统;

使用System.Collections;

使用System.IO;

使用System.Runtime.Serialization;

使用System.Runtime.Serialization.Formatters.Binary ;


命名空间SerializationSurrogateTest

{

公共课堂家长


{

私有字符串_name;


公共字符串名称{get {return _name; } set {_name = value; } $

private ArrayList _children;

public ArrayList Children {get {return _children; } $

public Parent()

{

_children = new ArrayList();

}

公共覆盖字符串ToString()


{

返回名称;

}

}

公共舱儿童


{

私人字符串_name;


public string Name {get {return _name; } set {_name = value; } $

public Child()

{


}

公共覆盖字符串ToString()


{

返回姓名;

}

}

公共类代理:ISerializationSurrogate


{

#region ISerializationSurrogate成员

public void GetObjectData(object obj,SerializationInfo info,

StreamingContext上下文)

{

if(obj is Parent)


{

info.AddValue(" children",(Child [])((Parent)obj).Children.ToArray(

typeof(Child)),typeof(Child []));

info.AddValue(" name",((Parent)obj).Name);


}

else if (obj是孩子)


{

info.AddValue(" name",((Child)obj).Name);
< br $>
}

Console.WriteLine(序列化{0}:{1},obj.GetType()。名称,

obj .ToString());

}

公共对象SetObjectData(object obj,SerializationInfo info,

StreamingContext context,ISurrogateSelector selector)


{

if(obj is Parent)


{

//对象c = info.GetValue(" children",typeof(object []));

Child [] children =(Child [])info.GetValue(" children",typeof(

Child []));

((Parent)obj)。 Children.Clear();

((Parent)obj)。Kidild.AddRange(children);

((Parent)obj).Name =(string)info。 GetValue(" name",typeof(object

));


}

else if(obj is Child)


{

((Child)obj).Name =(string)info.GetValue(" name",typeof(object)

);

}

Console.WriteLine(" Deserializing {0}:{1}",obj.GetType()。Name,

obj.ToString());

返回obj;

}

#endregion

}

///< summary>

/// StartHere的摘要描述。

///< / summary>

公共类StartHere


{

///< summary>

///应用程序的主要入口点。

///< / summary>

[STAThread]

static void Main()


{

Child child1 = new Child() ;

child1.Name =" Child1";

Child child2 = new Child();

child2.Name =" Child2" ;

父母=新父母();

parent.Name =" Parent1" ;;

parent.Children.Add(child1) ;

parent.Children.Add(child2);


SurrogateSelector selector = new SurrogateSelector();

selector.AddSurrogate( typeof(Parent),

new StreamingContext(StreamingContextStates.All),

new Surrogate());

selector.AddSurrogate(typeof(Child) ),

新的StreamingContext(StreamingContextStates.All),

n ew Surrogate());

MemoryStream stream = new MemoryStream();

IFormatter formatter = new BinaryFormatter();

formatter.SurrogateSelector =选择器;

formatter.Serialize(stream,parent);

stream.Position = 0;

object result = formatter.Deserialize(stream) ;

}

}


}

Can someone please help me and tell my why the following code is not
working, and hopefully how to get it working?

What I am trying to do is make a serialization surrogate that stores,
amongst other things, and array of objects that are also serialised by
the same surrogate. It serializes alright, but when it comes to
deserialization, the array comes out as an array (correct length) of
nulls. grrr... I''m pulling my hair out!!

Any help really appreciated.

Cheers
Greg

------ CODE START HERE ------
using System;
using System.Collections;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace SerializationSurrogateTest
{
public class Parent

{
private string _name;

public string Name { get { return _name; } set { _name = value; } }
private ArrayList _children;
public ArrayList Children { get { return _children; } }
public Parent()
{
_children = new ArrayList();
}
public override string ToString()

{
return Name;
}
}
public class Child

{
private string _name;

public string Name { get { return _name; } set { _name = value; } }
public Child()
{

}
public override string ToString()

{
return Name;
}
}
public class Surrogate : ISerializationSurrogate

{
#region ISerializationSurrogate Members
public void GetObjectData(object obj, SerializationInfo info,
StreamingContext context)
{
if( obj is Parent )

{
info.AddValue( "children", (Child[])((Parent)obj).Children.ToArray(
typeof( Child ) ), typeof( Child[] ) );
info.AddValue( "name", ((Parent)obj).Name );

}
else if( obj is Child )

{
info.AddValue( "name", ((Child)obj).Name );

}
Console.WriteLine( "Serializing {0}: {1}", obj.GetType().Name,
obj.ToString() );
}
public object SetObjectData(object obj, SerializationInfo info,
StreamingContext context, ISurrogateSelector selector)

{
if( obj is Parent )

{
//object c = info.GetValue( "children", typeof( object[] ) );
Child[] children = (Child[])info.GetValue( "children", typeof(
Child[] ) );
((Parent)obj).Children.Clear();
((Parent)obj).Children.AddRange( children );
((Parent)obj).Name = (string)info.GetValue( "name", typeof( object
) );

}
else if( obj is Child )

{
((Child)obj).Name = (string)info.GetValue( "name", typeof( object )
);
}
Console.WriteLine( "Deserializing {0}: {1}", obj.GetType().Name,
obj.ToString() );
return obj;
}
#endregion
}
/// <summary>
/// Summary description for StartHere.
/// </summary>
public class StartHere

{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()

{
Child child1 = new Child();
child1.Name = "Child1";
Child child2 = new Child();
child2.Name = "Child2";
Parent parent = new Parent();
parent.Name = "Parent1";
parent.Children.Add( child1 );
parent.Children.Add( child2 );

SurrogateSelector selector = new SurrogateSelector();
selector.AddSurrogate( typeof( Parent ),
new StreamingContext( StreamingContextStates.All ),
new Surrogate() );
selector.AddSurrogate( typeof( Child ),
new StreamingContext( StreamingContextStates.All ),
new Surrogate() );
MemoryStream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.SurrogateSelector = selector;
formatter.Serialize( stream, parent );
stream.Position = 0;
object result = formatter.Deserialize( stream );
}
}

}

推荐答案

序列化的复杂性让你感到震惊。您的父对象

未构建。它直接嵌入到内存中。这意味着你的

集合

被淘汰,并且没有被设置为新的ArrayList ......我建议写一下

你的父母如下,以便在访问时构建一个新的数组列表。


public class Parent {

private string _name;

public string Name {get {return _name; } set {_name = value; } $

private ArrayList _children;


public ArrayList Children {

get {

if(

if) _children == null){

_children = new ArrayList();

}


return _children;

}

}


公共覆盖字符串ToString(){

返回名称;


}

}

-

贾斯汀罗杰斯

DigiTec Web Consultants,LLC。

博客: http://weblogs.asp.net/justin_rogers


" gregbacchus" < GR ********* @ hotmail.com>在消息中写道

news:11 ********************* @ z14g2000cwz.googlegro ups.com ...
You are getting whacked by the intricacies of serialization. Your parent object
isn''t constructed. It is blitted into memory directly. That means your
collections
are nulled out and aren''t being set to a new ArrayList... I''d recommend writing
your parent as follows so that a new array-list is constructed upon access.

public class Parent {
private string _name;
public string Name { get { return _name; } set { _name = value; } }
private ArrayList _children;

public ArrayList Children {
get {
if ( _children == null ) {
_children = new ArrayList();
}

return _children;
}
}

public override string ToString() {
return Name;

}
}
--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

"gregbacchus" <gr*********@hotmail.com> wrote in message
news:11*********************@z14g2000cwz.googlegro ups.com...
有人可以帮助我并告诉我为什么下面的代码不能正常工作,并希望如何让它工作?

我想做的是做一个序列化代理存储,
等等,以及由同一个代理人序列化的对象数组。序列化正常,但是当涉及到反序列化时,数组以数组(正确长度)的形式出现。 grrr ...我正在拔头发!!

任何帮助都非常感激。

干杯
Greg

- -----代码从这里开始------
使用System;
使用System.Collections;
使用System.IO;
使用System.Runtime.Serialization;
使用System.Runtime.Serialization.Formatters.Binary;

命名空间SerializationSurrogateTest

{
public class Parent

{
私有字符串_name;

公共字符串名称{get {return _name; } set {_name = value;私有ArrayList _children;

public ArrayList Children {get {return _children;公共父()

{
_children = new ArrayList();

}

公共覆盖字符串ToString()

{
返回姓名;

}
}

公共类儿童

{
私有字符串_name;

公共字符串名称{get {return _name; } set {_name = value;公共孩子()

{

}

公共覆盖字符串ToString()

{
返回姓名;

}
}

公共类代理人:ISerializationSurrogate

{
#region ISerializationSurrogate会员

public void GetObjectData(object obj,SerializationInfo info,
StreamingContext context)

{
if(obj is Parent)

{
info.AddValue(" children",(Child [])((Parent)obj).Children.ToArray(
typeof(Child)),typeof(Child []) );
info.AddValue(" name",((Parent)obj).Name);

}

else if(obj is Child)

{
info.AddValue(" name",((Child)obj).Name);

}

控制台。 WriteLine(序列化{0}:{1},obj.GetType()。名称,
obj.ToString());

}

公共对象SetObjectData(对象obj,SerializationInfo信息,
StreamingContext上下文,ISurr ogateSelector选择器)

{
如果(obj是父母)

{object c = info.GetValue(" children",typeof) (object []));
Child [] children =(Child [])info.GetValue(" children",typeof(
Child []));
((Parent) obj).Children.Clear();
((Parent)obj)。Kidild.AddRange(children);
((Parent)obj).Name =(string)info.GetValue(" name" ;,typeof(object
));

}

else if(obj is Child)

{
( (Child)obj).Name =(string)info.GetValue(" name",typeof(object)
);

}

Console.WriteLine (反序列化{0}:{1},obj.GetType()。名称,
obj.ToString());
返回obj;

}

#endregion

}

///< summary>
/// StartHere的摘要说明。
/ //< / summary>
公共课StartHere

//
// << summary>
///的主要切入点应用。
///< / summary>
[STAThread]
static void Main()

{child child child1 = new Child() ;
child1.Name =" Child1";
Child child2 = new Child();
child2.Name =" Child2";
Parent parent = new Parent() ;
parent.Name =" Parent1";
parent.Children.Add(child1);
parent.Children.Add(child2);

SurrogateSelector选择器= new SurrogateSelector();
selector.AddSurrogate(typeof(Parent),
new StreamingContext(StreamingContextStates.All),
new Surrogate());
selector.AddSurrogate(typeof (孩子),
新的StreamingContext(StreamingContextStates.All),
新的Surrogate());

MemoryStream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.SurrogateSelector = selector;

formatter.Serialize(stream,parent);

stream.Position = 0;
对象result = formatter.Deserialize (流);
}
}

}
Can someone please help me and tell my why the following code is not
working, and hopefully how to get it working?

What I am trying to do is make a serialization surrogate that stores,
amongst other things, and array of objects that are also serialised by
the same surrogate. It serializes alright, but when it comes to
deserialization, the array comes out as an array (correct length) of
nulls. grrr... I''m pulling my hair out!!

Any help really appreciated.

Cheers
Greg

------ CODE START HERE ------
using System;
using System.Collections;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace SerializationSurrogateTest
{
public class Parent

{
private string _name;

public string Name { get { return _name; } set { _name = value; } }
private ArrayList _children;
public ArrayList Children { get { return _children; } }
public Parent()
{
_children = new ArrayList();
}
public override string ToString()

{
return Name;
}
}
public class Child

{
private string _name;

public string Name { get { return _name; } set { _name = value; } }
public Child()
{

}
public override string ToString()

{
return Name;
}
}
public class Surrogate : ISerializationSurrogate

{
#region ISerializationSurrogate Members
public void GetObjectData(object obj, SerializationInfo info,
StreamingContext context)
{
if( obj is Parent )

{
info.AddValue( "children", (Child[])((Parent)obj).Children.ToArray(
typeof( Child ) ), typeof( Child[] ) );
info.AddValue( "name", ((Parent)obj).Name );

}
else if( obj is Child )

{
info.AddValue( "name", ((Child)obj).Name );

}
Console.WriteLine( "Serializing {0}: {1}", obj.GetType().Name,
obj.ToString() );
}
public object SetObjectData(object obj, SerializationInfo info,
StreamingContext context, ISurrogateSelector selector)

{
if( obj is Parent )

{
//object c = info.GetValue( "children", typeof( object[] ) );
Child[] children = (Child[])info.GetValue( "children", typeof(
Child[] ) );
((Parent)obj).Children.Clear();
((Parent)obj).Children.AddRange( children );
((Parent)obj).Name = (string)info.GetValue( "name", typeof( object
) );

}
else if( obj is Child )

{
((Child)obj).Name = (string)info.GetValue( "name", typeof( object )
);
}
Console.WriteLine( "Deserializing {0}: {1}", obj.GetType().Name,
obj.ToString() );
return obj;
}
#endregion
}
/// <summary>
/// Summary description for StartHere.
/// </summary>
public class StartHere

{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()

{
Child child1 = new Child();
child1.Name = "Child1";
Child child2 = new Child();
child2.Name = "Child2";
Parent parent = new Parent();
parent.Name = "Parent1";
parent.Children.Add( child1 );
parent.Children.Add( child2 );

SurrogateSelector selector = new SurrogateSelector();
selector.AddSurrogate( typeof( Parent ),
new StreamingContext( StreamingContextStates.All ),
new Surrogate() );
selector.AddSurrogate( typeof( Child ),
new StreamingContext( StreamingContextStates.All ),
new Surrogate() );
MemoryStream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.SurrogateSelector = selector;
formatter.Serialize( stream, parent );
stream.Position = 0;
object result = formatter.Deserialize( stream );
}
}

}



谢谢你回复Justin,但是这个是另一个问题。

一个我已经修复过的(只是没有在这段代码中显示)通过调用

默认构造函数明显 - 如下所示。我的实际问题



info.GetValue(" children",typeof(ArrayList))

作为null的arraylist返回。


Greg

公共对象SetObjectData(对象obj,SerializationInfo信息,

StreamingContext上下文,ISurrogateSelector选择器)

{

ConstructorInfo构造函数= obj.GetType()。GetConstructor(new

Type [0]);

obj = constructor .Invoke(新对象[0]);

....

Thanks for you reply Justin, but this is another issue all together.
One which I already fixed (just didn''t show in this code) by calling
the default constructor explicity - as shown below. My actual problem
is that
info.GetValue( "children", typeof( ArrayList ) )
comes back as an arraylist of nulls.

Greg
public object SetObjectData(object obj, SerializationInfo info,
StreamingContext context, ISurrogateSelector selector)
{
ConstructorInfo constructor = obj.GetType().GetConstructor( new
Type[0] );
obj = constructor.Invoke( new object[0] );
....


使用我要做的代码粘贴下面,这只是你的代码与

父改变序列化显然是基于最后的两个写字线调用




使用System;

使用System.Collections;

使用System.IO;

使用System.Runtime.Serialization;

使用System.Runtime.Serialization.Formatters.Binary;


namespace SerializationSurrogateTest {

public class Parent {

private string _name;

public string Name {get {return _name; } set {_name = value; } $

private ArrayList _children;


public ArrayList Children {

get {

if(

if) _children == null){

_children = new ArrayList();

}


return _children;

}

}


公共覆盖字符串ToString(){

返回名称;


}

}

公共类儿童

{

private string _name;


public string Name {get {return _name; } set {_name = value; } $

public Child()

{


}

公共覆盖字符串ToString()


{

返回姓名;

}

}

public class Surrogate:ISerializationSurrogate {

public void GetObjectData(object obj,SerializationInfo info,

StreamingContext context){

if(obj is Parent) {

info.AddValue(" children",

(Child [])((Parent)obj).Children.ToArray(typeof(Child)),typeof( Child []));

info.AddValue(" name",((Parent)obj).Name);

} else if(obj is Child){

info.AddValue(" name",((Child)obj).Name);

}

Console.WriteLine("序列化{0}:{1}",obj.GetType()。名称,

obj.ToString());

}

public object SetObjectData(object obj,SerializationInfo info,

StreamingContext context,ISurrogateSelector selector){

if(ob j是Parent){

// object c = info.GetValue(" children",typeof(object []));

Child [] children =(Child [])info.GetValue(" children",

typeof(Child []));

((Parent)obj).Children.Clear();

((父)obj)。Kidild.AddRange(儿童);

((父)obj).Name =(字符串)info.GetValue(" name", typeof(

object));


}否则if(obj is Child){

((Child)obj)。 Name =(string)info.GetValue(" name",typeof(

object));


}


Console.WriteLine(" Deserializing {0}:{1}",obj.GetType()。Name,

obj.ToString());

返回obj;

}

}

公共类StartHere {

[STAThread]

private static void Main(){

Child child1 = new Child();

child1.Name =" Child1";

Child child2 = new Child();

child2.Name =" Child2";


父母=新父母();

parent.Name =" Parent1" ;;

parent.Children.Add(child1);

parent.Children.Add(child2);


SurrogateSelector selector = new SurrogateSelector() ;

selector.AddSurrogate(typeof(Parent),new StreamingContext(

StreamingContextStates.All),new Surrogate());

selector。 AddSurrogate(typeof(Child),new StreamingContext(

StreamingContextStates.All),new Surrogate());


MemoryStream stream = new MemoryStream();

IFormatter formatter = new BinaryFormatter();

formatter.SurrogateSelector = selector;

formatter.Serialize(stream,parent);

stream.Position = 0;

父结果=(父)formatter.Deserialize(stream);


for(int i = 0;我< result.Children.Count; i ++){

Console.WriteLine(result.Children [i]);

}

}

}

}

-

贾斯汀罗杰斯

DigiTec网络顾问有限责任公司。

博客: http://weblogs.asp.net/justin_rogers


" Greg Bacchus" < GR ********* @ hotmail.com>在消息中写道

news:11 ********************** @ c13g2000cwb.googlegr oups.com ...
Using the code I''m about to paste below, which is just your code with
the parent change the serialization is clearly working based on the last
two writeline calls.

using System;
using System.Collections;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace SerializationSurrogateTest {
public class Parent {
private string _name;
public string Name { get { return _name; } set { _name = value; } }
private ArrayList _children;

public ArrayList Children {
get {
if ( _children == null ) {
_children = new ArrayList();
}

return _children;
}
}

public override string ToString() {
return Name;

}
}
public class Child
{
private string _name;

public string Name { get { return _name; } set { _name = value; } }
public Child()
{

}
public override string ToString()

{
return Name;
}
}
public class Surrogate : ISerializationSurrogate {
public void GetObjectData(object obj, SerializationInfo info,
StreamingContext context) {
if( obj is Parent ) {
info.AddValue( "children",
(Child[])((Parent)obj).Children.ToArray(typeof( Child ) ), typeof( Child[] ) );
info.AddValue( "name", ((Parent)obj).Name );
} else if( obj is Child ) {
info.AddValue( "name", ((Child)obj).Name );
}
Console.WriteLine( "Serializing {0}: {1}", obj.GetType().Name,
obj.ToString() );
}

public object SetObjectData(object obj, SerializationInfo info,
StreamingContext context, ISurrogateSelector selector) {
if( obj is Parent ) {
//object c = info.GetValue( "children", typeof( object[] ) );
Child[] children = (Child[])info.GetValue( "children",
typeof(Child[] ) );
((Parent)obj).Children.Clear();
((Parent)obj).Children.AddRange( children );
((Parent)obj).Name = (string)info.GetValue( "name", typeof(
object) );

} else if( obj is Child ) {
((Child)obj).Name = (string)info.GetValue( "name", typeof(
object ) );

}

Console.WriteLine( "Deserializing {0}: {1}", obj.GetType().Name,
obj.ToString() );
return obj;
}
}
public class StartHere {
[STAThread]
private static void Main() {
Child child1 = new Child();
child1.Name = "Child1";

Child child2 = new Child();
child2.Name = "Child2";

Parent parent = new Parent();
parent.Name = "Parent1";

parent.Children.Add( child1 );
parent.Children.Add( child2 );

SurrogateSelector selector = new SurrogateSelector();
selector.AddSurrogate( typeof( Parent ), new StreamingContext(
StreamingContextStates.All ), new Surrogate() );
selector.AddSurrogate( typeof( Child ), new StreamingContext(
StreamingContextStates.All ), new Surrogate() );

MemoryStream stream = new MemoryStream();
IFormatter formatter = new BinaryFormatter();
formatter.SurrogateSelector = selector;
formatter.Serialize( stream, parent );
stream.Position = 0;
Parent result = (Parent) formatter.Deserialize( stream );

for(int i = 0; i < result.Children.Count; i++) {
Console.WriteLine(result.Children[i]);
}
}
}
}
--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers

"Greg Bacchus" <gr*********@hotmail.com> wrote in message
news:11**********************@c13g2000cwb.googlegr oups.com...
谢谢你回复Justin,但这是另一个问题。
一个我已经修复过的(只是没有在这段代码中显示)通过调用
默认的构造函数explicity - as如下所示。我的实际问题是
info.GetValue(" children",typeof(ArrayList))
作为零点的arraylist回来。

Greg

公共对象SetObjectData(对象obj,SerializationInfo信息,
StreamingContext上下文,ISurrogateSelector选择器)
{
ConstructorInfo构造函数= obj.GetType()。GetConstructor(new
输入[0]);
obj = constructor.Invoke(new object [0]);
...
Thanks for you reply Justin, but this is another issue all together.
One which I already fixed (just didn''t show in this code) by calling
the default constructor explicity - as shown below. My actual problem
is that
info.GetValue( "children", typeof( ArrayList ) )
comes back as an arraylist of nulls.

Greg
public object SetObjectData(object obj, SerializationInfo info,
StreamingContext context, ISurrogateSelector selector)
{
ConstructorInfo constructor = obj.GetType().GetConstructor( new
Type[0] );
obj = constructor.Invoke( new object[0] );
...



这篇关于SerializationSurrogate Arrays问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆