C#的浅拷贝和深拷贝
答案:3 悬赏:20 手机版
解决时间 2021-04-02 16:15
- 提问者网友:雾里闻花香
- 2021-04-01 22:37
C#的浅拷贝和深拷贝
最佳答案
- 五星知识达人网友:长青诗
- 2021-04-01 23:45
string是个比较特别的引用类型,以下是转的:
(3)数组的clone()方法所创建的是数组的浅表副本。即只会复制数组的元素,而并不会复制数组所引用的对象。也就是说,只复制对象指针,而不复制对象本身。
例如:
Class1[] arrayCls1=new
Class1[3];
//创建对象数组arrayCls1
arrayCls1[2] = new
Class1(); //为数组arrayCls1第3个元素赋值
Class1[] arrayCls2 =
(clsCase1[])arrayCls1.Clone();//创建对象数组arrayCls2,并把arrayCls1复制于他
arrayCls2[2].clsText =
"CHAMPION"; //修改数组arrayCls2第3个元素的clsText属性
private class Class1
{
private
string _value = "MILAN";
public
string clsText
{
set{
_value = value; }
get{
return _value; }
}
}
最后结果为:arrayCls1[2].clsText=CHAMPION,arrayCls2[2].clsText=CHAMPION
再看一个例子
string[]
arrayStr1 = {"MILAN","INTER","MU" };
string[]
arrayStr2 = (string[])(arrayStr1.Clone());
arrayStr2[2]
= "ROMA";
最后结果为:arrayStr1[2]=MU,arrayStr2[2]=ROMA
为何类Class1和string都是引用类型,输出的结果却不同呢?
因为string是个特殊的引用类型,每当被赋值时,都会创建一个新的string的对象。
所以string数组在clone一个新数组后,对新数组某元素赋值后,由于创建了一个新的string的对象,所以元素中存放的字符串指针也随之改变了。追问教我怎么看清一个对象是怎么实现的内部过程。好像和CLR什么有关系吧。平时听别人说过什么IL反汇编可以是羡慕不知道是不是这样,还有你的最后一句话我个人的理解应该是利用克隆之后在新的堆里面从新对象,在新的栈里面重新分配值吧~!(还有我个人也感觉这个string[]数组)和别的引用对象还是有很大的区别的,内部做了很多东西
(3)数组的clone()方法所创建的是数组的浅表副本。即只会复制数组的元素,而并不会复制数组所引用的对象。也就是说,只复制对象指针,而不复制对象本身。
例如:
Class1[] arrayCls1=new
Class1[3];
//创建对象数组arrayCls1
arrayCls1[2] = new
Class1(); //为数组arrayCls1第3个元素赋值
Class1[] arrayCls2 =
(clsCase1[])arrayCls1.Clone();//创建对象数组arrayCls2,并把arrayCls1复制于他
arrayCls2[2].clsText =
"CHAMPION"; //修改数组arrayCls2第3个元素的clsText属性
private class Class1
{
private
string _value = "MILAN";
public
string clsText
{
set{
_value = value; }
get{
return _value; }
}
}
最后结果为:arrayCls1[2].clsText=CHAMPION,arrayCls2[2].clsText=CHAMPION
再看一个例子
string[]
arrayStr1 = {"MILAN","INTER","MU" };
string[]
arrayStr2 = (string[])(arrayStr1.Clone());
arrayStr2[2]
= "ROMA";
最后结果为:arrayStr1[2]=MU,arrayStr2[2]=ROMA
为何类Class1和string都是引用类型,输出的结果却不同呢?
因为string是个特殊的引用类型,每当被赋值时,都会创建一个新的string的对象。
所以string数组在clone一个新数组后,对新数组某元素赋值后,由于创建了一个新的string的对象,所以元素中存放的字符串指针也随之改变了。追问教我怎么看清一个对象是怎么实现的内部过程。好像和CLR什么有关系吧。平时听别人说过什么IL反汇编可以是羡慕不知道是不是这样,还有你的最后一句话我个人的理解应该是利用克隆之后在新的堆里面从新对象,在新的栈里面重新分配值吧~!(还有我个人也感觉这个string[]数组)和别的引用对象还是有很大的区别的,内部做了很多东西
全部回答
- 1楼网友:刀戟声无边
- 2021-04-02 02:25
请教下2位: 为什么我定义的类型里面有个Hashtable,这个Hashtable应该是引用类型吧?为什么无法达到浅拷贝的效果啊?//add 20140520
//我明白了,因为v1.parts = ht1完全改变了v1中parts的引用,此时跟v5的parts已经完全断开了关系.
//只有不改变引用时,浅拷贝才可以相互影响
代码如下:
类型: [Serializable]
public class Vehicle : ICloneable
{
public Hashtable _parts = new Hashtable();
public Hashtable parts { get { return _parts; } set { _parts = value; } }
public static Vehicle operator +(Vehicle v1, Vehicle v2)
{
Hashtable ht = new Hashtable();
foreach (DictionaryEntry item in v1.parts)
{
ht.Add(item.Key, item.Value);
}
foreach (DictionaryEntry item in v2.parts)
{
ht.Add(item.Key, item.Value);
}
v2.parts = ht;
return v2;
}
public object this[string key]
{
get
{
return parts[key];
}
set
{
parts[key] = value;
//parts.Add(key, value);
}
}
public static implicit operator Vehicle(Hashtable ht)
{
Vehicle v = new Vehicle();
v.parts = ht;
return v;
}
#region ICloneable Members
public object Clone()
{
return this.MemberwiseClone();
}
#endregion
public Vehicle Shallow()
{
return Clone() as Vehicle;
}
public Vehicle DeepClone()
{
using (Stream objectstream = new MemoryStream())
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(objectstream, this);
objectstream.Seek(0, SeekOrigin.Begin);
return formatter.Deserialize(objectstream) as Vehicle;
}
}
}
调用: Vehicle v1 = new Vehicle()
Hashtable ht2 = new Hashtable();
ht2.Add("str1","haha");
ht2.Add("str2","hehe");
v1.parts = ht2;
Vehicle v4 = v1.DeepClone();
Vehicle v5 = v1.Shallow() as Vehicle;//v5是v1的浅拷贝
EnumerateHashtable(v1);//此方法是枚举v1中的Hashtable
Console.WriteLine("-------------");
EnumerateHashtable(v4);
Console.WriteLine("-------------");
EnumerateHashtable(v5);
Console.WriteLine("=============");
Hashtable ht1 = new Hashtable();
v4.parts = ht1;
v1.parts = ht1;//v1的hashtable重置了,问题: 但v5的没有重置,求解
EnumerateHashtable(v1);
Console.WriteLine("-------------");
EnumerateHashtable(v4);
Console.WriteLine("-------------");
EnumerateHashtable(v5);
Console.WriteLine("=============");
Console.ReadLine();
结果:str1: haha
str2: hehe
-------------
str1: haha
str2: hehe
-------------
str1: haha
str2: hehe
=============
-------------
-------------
str1: haha
str2: hehe
=============
- 2楼网友:未来江山和你
- 2021-04-02 01:24
简单来说就是拷贝新的一份赋值给了bs,而修改str和bs是没有关系的
string不能单纯的理解为引用类型,其实更具备值类型的特征,因为使用的太频繁所以进行了特殊处理
string不能单纯的理解为引用类型,其实更具备值类型的特征,因为使用的太频繁所以进行了特殊处理
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
推荐资讯