读《.NET(C#):理解值类型/引用类型,装箱/拆箱,Object类》 有感,小白类文

原文地址: http://www.cnblogs.com/mgen/archive/2011/05/06/2038339.html 该文作者为:Mgen  90后大牛MVP(我也是90后为啥差这么多呢+_+)

写此目的:

   由于我基础本较差,于是在项目遇到很多问题,所以回过头来学习基础,(由于公司程序就是我一个,所以只能到处找文章自己钻研——|||)  ,偶然遇到Mgen大牛的blog,发现Megn大牛也是专注于C# C/S开发,而且技术水平很高(感觉找到偶像了— —||)。于是下定决心,开始开始看大牛的 文章。写此文留给自己

正文:(原文中内容不再这里阐述)

  1:Object.Equals

    此方法作用 比较两个实例是否相同,但是只支持.net 内置的类型 如:int string 等,自定义的类无法实现该功能 必须 重写 Equals 该方法(注:这里使用object.Equals(o1,o2)))

(修改)
object类的代码:(可以看到 调用object.
Equals()方法 所以如果是值类型那么比对值本身,如果是引用类型则比较比较指针是否相同

public static bool Equals(object objA, object objB) { return ((objA == objB) || (((objA != null) && (objB != null)) && objA.Equals(objB)));
} public virtual bool Equals(object obj) { return RuntimeHelpers.Equals(this, obj); }

 

 代码:

 1 class Program
 2     {
 3         static void Main()
 4         {
 5             var mc1 = new MyClass { Value = 1, Name = "N" };
 6             var mc2 = new MyClass { Value = 1, Name = "N" };
 7             var mc21 = new MyClass2 { Value = 1, Name = "N" };
 8             var mc22 = new MyClass2 { Value = 1, Name = "N" };
 9 
10             Console.WriteLine(object.Equals(mc1, mc2)); //输出:false 
11             Console.WriteLine(object.Equals(mc21, mc22)); //输出:true , 因为 手动重写Equals
12             Console.WriteLine(mc21 == mc22);  //输出:true , 因为 手动重载运算符 ==
13             Console.WriteLine(
14                object.Equals(
15                     new string(new char[] { 'a', 'b', 'c' }), 
16                     new string(new char[] { 'a', 'b', 'c' })
17                     )); // 输出:true , string 底层 重写 Equals 方法。。
18             Console.WriteLine("List:" + object.Equals(new List<string> { "a" }, new List<string> { "a" })); // 由于 List 没事实现 Equals,所以 false
19 33         }    
34     }
35 
36     class MyClass
37     {
38         public int Value { get; set; }
39 
40         public string Name { get; set; }
41     }
42 
43     class MyClass2
44     {
45         public int Value { get; set; }
46 
47         public string Name { get; set; }
48 
49         public override bool Equals(object obj)
50         {
51             var temp=obj as MyClass2;
52             if (temp.Value==this.Value && temp.Name==this.Name)
53             {
54                 return true;
55             }
56             return base.Equals(obj);
57         }
58 
59         //吐槽 一下 要重载 ==, 必须 重载 !=    — —|||
60         public static bool operator ==(MyClass2 c1, MyClass2 c2)
61         {
62             if (c1.Name==c2.Name && c1.Value==c1.Value)
63             {
64                 return true;
65             }
66             return false;
67         }
68 
69         public static bool operator !=(MyClass2 c1, MyClass2 c2)
70         {
71             if (c1.Name == c2.Name && c1.Value == c1.Value)
72             {
73                 return false;
74             }
75             return true;
76         }
77     }

 

 细看看代码,发现

   1、如果引用类型实现 Equals() 方法 必须 要 重写。。。 如果不手动 写 那么 返回全是 false

   2、如果引用类型值类型要实现== 和!= 必须 重载运算符(注:实现重载需要 public static 返回值类型 operator 符号(类实例1,类实例2)

   

2.MemberwiseClone()  这个方法创建一个浅表副本,具体来说就是创建一个新对象,然后将当前对象的非静态字段复制到该新对象。如果字段是值类型的,则对该字段执行逐位复制。如果字段是引用类型,则复制引用但不复制引用的对象;因此,原始对象及其复本引用同一对象。(这是我从百度的内容。。。然后 我写了一下代码测试了下)

 1 class Program
 2     {
 3         static void Main()
 4         {
 5             
 6             ////MemberwiseClone() 方法测试
 7 
 8            var t1 = new TestCopy { 
 9                TC = new TestClass { iValue = 1, sValue = "a" }, 
10                TS = new TestStruct { iValue = 1, sValue = "a" } };
11            var t2 = t1.GetCopy();
12            var t3 = t1;
13            t1.TC = null; //此处 TC为 属性。。。更改此属性的指针       
14            t1.TS = new TestStruct(); //此处 TS为 属性。。。更改此属性的值  
15            Console.WriteLine(t1.TC + "  "  + t1.TS.iValue); //输出 空 0
16            Console.WriteLine(t2.TC + "  "  + t2.TS.iValue); //输出 非空 1
17            Console.WriteLine(t3.TC + "  "  + t3.TS.iValue); //输出 空 0
18         }    
19     }
20 
21     struct TestStruct //测试 结构
22     {
23         public int iValue { get; set; }
24         public string sValue { get; set; }    
25     }
26 
27     class TestClass  //测试类
28     {
29         public int iValue { get; set; }
30         public string sValue { get; set; }
31     }
32 
33     class TestCopy
34     {
35         public TestClass TC { get; set; }
36         public TestStruct TS { get; set; }
37 
38      
39 
40         public TestCopy GetCopy()
41         {
42             return this.MemberwiseClone() as TestCopy;
43         }
44     }

 

  验证成果 。。。如果类中含有值类型。。。那么复制一个新对象,如果引用对象 复制指针。。。(复制指针有时候 还是 挺有用的。。比如说 a指向一个对象 ,我把b复制这个指针 ,如果 a 修改了指针。。。那么b还是指向 a的原值。。。当然如果你修改 指针指向的 内容 那就 没啥用处了。。— —||||因为 是一个指针)如我在代码中 修改TC属性为null 那么,复制的副本中TC是不受影响的。(可以吧TC 当成“值类型” 咳咳~)

 最后: 这个 结果还是挺乱的~

 3、在结构体中 实现重载 !=与 ==  (因为在 值类型中 Equals 方法是 对值得判断,所以,重载运算符 方便多了)

 1 struct TestStruct
 2     {
 3         public string a { get; set; }
 4 
 5         public int b { get; set; }
 6 
 7         public static bool operator ==(TestStruct v1, TestStruct v2)
 8         {
 9             return v1.Equals(v2);
10         }
11 
12         public static bool operator !=(TestStruct v1, TestStruct v2)
13         {
14             return v1.Equals(v2);
15         }
16     }

static void Main(string[] args)
{
var v1 = new TestStruct { a="2",b=1 };
var v2 = new TestStruct { a="2",b=1 };

Console.WriteLine(v1==v2);

}

 

 

 

posted @ 2013-04-14 20:34  沐松  阅读(491)  评论(3)    收藏  举报