读《.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);
}

浙公网安备 33010602011771号