百分求教C#赋值问题

zhangbat 2004-01-06 08:55:36
//如下代码
ArrayList arrL = new ArrayList();
ArrayList arrM = new ArrayList();

Button btnX = new Button();
btnX.Text = "original";
arrL.Add(btnX);
arrL.Add(new ListBox());

arrM = arrL;

((Button)arrL[0]).Text = "XXX";

Label1.Text = ((Button)arrM[0]).Text;

/***********************
我希望能够得到一个arrL 的副本,但是C#给我的确是一个引用,就是说
我修改了arrL中对象的属性之后相应的arrM中的对象的属性也会发生改变。
我已经试过了很多的方法都不行,请教谁能解决这个问题。一旦证实有效,将以百分相赠
(例如用了下面这一堆代码
ArrayList arrL = new ArrayList(arrControls);

// arrControls = null;
// arrControls = new ArrayList(arrL);
// arrControls = (ArrayList)arrL.Clone();
// //循环赋值
// ArrayList arrL = new ArrayList();
//
// for(int i = 0; i < arrControls.Count; i ++)
// {
// object objTemp = new object();
// objTemp = arrControls[i];
// arrL.Add(objTemp);
// }

***********************/
...全文
221 69 打赏 收藏 转发到动态 举报
写回复
用AI写文章
69 条回复
切换为时间正序
请发表友善的回复…
发表回复
brightheroes 2004-01-08
  • 打赏
  • 举报
回复
还是这个厉害:)
brightheroes 2004-01-08
  • 打赏
  • 举报
回复
Hi,

just wondering why you don't use the .NET serialization for the purpose of cloning an object. The advantage is -IMHO- that you have more control of what should be cloned and what not (simply mark a field with the NonSerialized attribute).

example:

[Serializable]class Foo: ICloneable{ [NonSerialized] public int TempVar; public string Text; public object Clone() { Stream stream=new MemoryStream(); try { BinaryFormatter bf = new BinaryFormatter(); bf.Serialize(stream, this); stream.Position=0; return bf.Deserialize(stream); } finally { stream.Close(); } }}


The Clone method is always the same and could therefore be placed in a utility class.
Just a thought...

Happy new Year
zhangbat 2004-01-07
  • 打赏
  • 举报
回复
to: xixigongzhu(夕夕公主)

谢谢你,按照你的方法已经初步实现了赋值的问题,
具体怎么用到我的工程中是我的事情了,

很开心这个困扰我多日的问题得到了解决。
这个帖子只能给200分,可是帮助我的朋友有这么多……,
我看这样吧,我另开帖子专门给你分你看好么?
zhangbat 2004-01-06
  • 打赏
  • 举报
回复
to:AhBian(阿扁)

可能真的是有问题,可是我只考虑实现目的,有什么好方法?
zhangbat 2004-01-06
  • 打赏
  • 举报
回复
TO:xixigongzhu(夕夕公主)
我服了!!
我在winform中运行就可以了,
在webform中就不行 ! :(

可是同样的代码呀……………………
xixigongzhu 2004-01-06
  • 打赏
  • 举报
回复
MethodInfo mi = typeof(Object).GetMethod("MemberwiseClone", BindingFlags.NonPublic|BindingFlags.Instance);
ArrayList list = new ArrayList();
list.Add(new Button());
((Button)list[0]).Text = "aa";
ArrayList list2 = new ArrayList();
list2.Add(mi.Invoke(list[0], null));
((Button)list[0]).Text = "bb";
Console.WriteLine(((Button) list[0]).Text);
Console.WriteLine(((Button) list2[0]).Text);


我这段运行结果是:
bb
aa
两者完全不一样呀。
xixigongzhu 2004-01-06
  • 打赏
  • 举报
回复
为什么在我的机子上可以呢?

虽然MemberwiseClone不能深层复制,但它改变了两个ArrayList中元素的引用,使得两者的元素引用不同的对象,所以应该不会出现楼主所说的问题拉。
AhBian 2004-01-06
  • 打赏
  • 举报
回复
值类型 <-> 引用类型

浅表复制 <-> 深度复制

设计理念有问题。
king678 2004-01-06
  • 打赏
  • 举报
回复
学习,帮顶
zhangbat 2004-01-06
  • 打赏
  • 举报
回复
to:cuike519(Power_mj)
报错,提示说“xxx.aspx 不是可序列化的对象”
:(
zhangbat 2004-01-06
  • 打赏
  • 举报
回复
to:xixigongzhu(夕夕公主)
果然如你所说,还是指向同一个对象

不行的:(
改成这样也不行
System.Reflection.MethodInfo mi = typeof(object).GetMethod("MemberwiseClone",System.Reflection.BindingFlags.NonPublic|System.Reflection.BindingFlags.Instance);

ArrayList arrL = new ArrayList();
ArrayList arrM = new ArrayList();

Button btnX = new Button();
btnX.Text = "original";
arrL.Add(btnX);
arrL.Add(new ListBox());

foreach(object objT in arrL)
{
object objM = new object();
objM = mi.Invoke(objT,null);
arrM.Add(objM);
}


((Button)arrL[0]).Text = "XXX";

Label1.Text = ((Button)arrM[0]).Text;
tongcheng 2004-01-06
  • 打赏
  • 举报
回复
学习
zhangbat 2004-01-06
  • 打赏
  • 举报
回复
对不起,刚才开了个会,
现在我试一下power_mj 和 xixigongzhu(夕夕公主) 的方法,

谢谢大家,

另外, acewang(平平安安过一年) ,我在上面有回复,我不能定义别的类的,因为我做的是接口
maximon 2004-01-06
  • 打赏
  • 举报
回复
关注,收藏
smartcreater01 2004-01-06
  • 打赏
  • 举报
回复
//clone ,MemberwiseClone 只能复制 value Type,and object's Reference
//换一种方式 :定义成类
public class myClass{
public static ArrayList GetArray(){
Private ArrayList arrL = new ArrayList();
Button btnX = new Button();
btnX.Text = "original";
arrL.Add(btnX);
arrL.Add(new ListBox());
return arrL;
}
}
ArrayList arrL = myClass.GetArray();
ArrayList arrM = myClass.GetArray();
cuike519 2004-01-06
  • 打赏
  • 举报
回复
前面提到的利用系列化的方法有如下的例子:
///
/// Clone the World object.
///
public object CloneEx()
{
BinaryFormatter bFormatter = new BinaryFormatter();
MemoryStream stream = new MemoryStream();
bFormatter.Serialize(stream, this);
stream.Seek(0, SeekOrigin.Begin);
World newWorld = (World)bFormatter.Deserialize(stream);
return newWorld;
}
cuike519 2004-01-06
  • 打赏
  • 举报
回复
不知楼主看上面给你的地址了没有!

http://www.codeproject.com/csharp/cloneimpl_class.asp
xixigongzhu 2004-01-06
  • 打赏
  • 举报
回复
关于MemberwiseClone,文档是这样描述的:
创建当前 Object 的浅表副本。浅表副本创建与原始对象具有相同类型的新实例,然后复制原始对象的非静态字段。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制该引用但不复制被引用的对象;这样,原始对象中的引用和复本中的引用指向同一个对象。
xixigongzhu 2004-01-06
  • 打赏
  • 举报
回复
其实只要方法存在,.net还是提供了调用的方式的,那就是Reflection API了:
先取到方法:
MethodInfo mi = typeof(Object).GetMethod("MemberwiseClone", BindingFlags.NonPublic|BindingFlags.Instance);

然后将arrM = arrL;这个用下面的替换:
ArrayList arrM = new ArrayList();

for(int i = 0; i < arrL.Count; i ++)
{
arrM.Add(mi.Invoke(arrL[i],null));
}
xixigongzhu 2004-01-06
  • 打赏
  • 举报
回复
思路:要实现复制,其实还是有个方法的,那就是Object的MemberwiseClone方法,但这个方法是保护的,不能直接调用。现在的问题是有没有办法来调用这个方法呢。
加载更多回复(49)

110,571

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧