深复制 序列化 比较
1、简单的对象复制是把一个对象的所有值传给另一个对象,值类型一般没有问题,但引用类型则存在一份的原因,前一对象修改,后一对象的值相应也发生了变化 ,这就存在问题,无法独立使用对象,所以需要深复制,把A类完全独立复制给B类,A与B之间无任何关系,这时就要用的ICloneable接口,两个类都要实现ICloneable接口,添加Clone方法,例子如下 :
static void Main(string[] args) { ClassB bb = new ClassB(); bb.Value = 22; bb.CA = new ClassA() { Value = 11 }; Console.WriteLine(bb.Value+":"+bb.CA.Value); ClassB newB = bb.Clone() as ClassB; Console.WriteLine(newB.Value+":::"+newB.CA.Value); bb.CA.Value = 33; Console.WriteLine(bb.Value+":"+bb.CA.Value); Console.WriteLine(newB.Value+":::"+newB.CA.Value); } } public class ClassA : ICloneable { public int Value { get; set; } public object Clone() { ClassA c = new ClassA(); c.Value = this.Value; return c; } } public class ClassB :ICloneable { public int Value { get; set; } public ClassA CA { get; set; } public object Clone() { ClassB b = new ClassB(); b.Value = this.Value; b.CA = (this.CA as ICloneable).Clone() as ClassA; return b; } }
注意红色代码
2、序列化
using (FileStream fs = new FileStream("1.txt", FileMode.Create)) { ClassB a = new ClassB() { Value = 11, CA = new ClassA() { Value = 11 } }; XmlSerializer xml = new XmlSerializer(typeof(ClassB)); xml.Serialize(fs, a); }
xml序列化
using (FileStream fs = new FileStream("3.txt", FileMode.Create)) { ClassA a = new ClassA() { Value = 11 }; BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(fs, a); }
[Serializable]
public class ClassA : ICloneable
{
。。。。
二进制序列化的对象前要加 [Serializable]
3、对象比较大小
class Program { static void Main(string[] args) { ClassA a = new ClassA() { Value = 4 }; ClassA b = new ClassA() { Value = 2 }; Console.WriteLine(a.CompareTo(b)); } } public class ClassA : IComparable { public int Value { get; set; } public int CompareTo(object obj) { return this.Value.CompareTo(((ClassA)obj).Value); } }
比较大小实现IComparable接口,如果比较对象相等,也可以用CompareTo,结果为0,则说明相等。
如果实现对对象的排序,比较大小等功能,就要对对象内实现CompareTo, Equals和GetHashCode方法,这样就能很方便的对对象集合进行排序和比较了,如下:
class MyClass : IComparable<MyClass> { public int Value { get; set; } public String Information { get; set; } /// <summary> /// 先按照Value字段值比较,如果Value值一样, /// 就按照Information字段值比较, /// 只有两个字段值都一样,才认为这两个对象相等 /// </summary> /// <param name="other"></param> /// <returns></returns> public int CompareTo(MyClass other) { if (other == null) { return -1; } int result=this.Value.CompareTo(other.Value); if (result == 0) { return this.Information.CompareTo(other.Information); } return result; } public override bool Equals(object obj) { if (obj == null || obj is MyClass == false) { return false; } return this.CompareTo(obj as MyClass)==0; } public override int GetHashCode() { return Value ; } public override string ToString() { return String.Format("Value:{0}\t Information:{1}\n", Value, Information) ; } } class Program { static void Main(string[] args) { var MyClasses = GenerateExampleCollection();//加载数据 Console.WriteLine("原始集合:"); MyClasses.ForEach((obj) => { Console.WriteLine(obj); }); MyClasses.Sort(); Console.WriteLine("\n排序之后:"); MyClasses.ForEach((obj) => { Console.WriteLine(obj); }); MyClass objToFind = new MyClass() { Value = 2,Information = "ABC" }; Console.WriteLine("\n查找对象:{0}", objToFind); int index = MyClasses.IndexOf(objToFind); Console.WriteLine("对象{0}在集合中的索引:{1}",objToFind,index); Console.ReadKey(); }
如果对象类不好修改,可以写一个中间类来实现比较
class MyComparer :IComparer<ClassA> { public int Compare(ClassA x, ClassA y) { return x.Value.CompareTo(y.Value); } }