标签:
ctrl+k+c 表示 注释;
ctrl+alt+F10 表示 生成函数;
ctrl+k+u 表示 取消注释
ctrl+k+D 和ctrl + k+f皆表示 调整为规范格式;
?
private static int GetMaxNumbers(params int[] pms)
{
int max = pms[0];
for (int i = 1; i < pms.Length; i++)
{
if (pms[i] > max)
{
max = pms[i];
}
}
return max;
}
?
调用:
int max = GetMaxNumbers(10, 45, 13, 45, 75, 56);
Console.WriteLine("最大值为{0}", max);
?
***&* 该程序意在决出最大值。
7. 如何判断一个数是否为质数:
????【这个数】%【除了1和它本身之外的任何整数】!=0
就说明这个数为质数!
8. Math.Round(double 变量名, 2);
????该句话的意思是:"使用四舍五入的方法,保留后面的两位小数";
9. IndexOf的使用小例:
有这么一个字符串,如下:
string ziFu = "患者:"我老是咳嗽",医生:"你说啥?",患者:"痰多有咳嗽,",医生:"哦,你咳嗽呀。",患者:"恩恩,你帮我看看",医生:"一有病呀,我们正在演戏。"";
????在这里注意,字符串数组可以看作是Char类型的数组,但本质不是char数组。可以当做数组来用!
int count = 0;
int index = 0;
//在邮箱账号中,为了保证用户输入了1个@,就应该让"变量名.LastIndexOf("@")==变量名.IndexOf("@")"即,就是保证最后出现的索引和第一次出现的索引相同。
while ((index = ziFu.IndexOf("咳嗽", index)) != -1)
{
count++;
index = index + "咳嗽".Length;
Console.WriteLine("第{0}次出现的索引为:{1}", count, index);
}
Console.WriteLine("咳嗽出现的总次数为{0}",count);
?
***&* 上面的ziFu.IndexOf("咳嗽", index)应该理解为:
变量名.IndexOf(string 参数1,int 参数2)
参数1为要搜索的字符串,参数2表示从索引为参数1的位置上开始搜索。且,返回值为int类型,代表着,从参数1开始,第一次出现的为值索引值!
?
10. 查询字符串中各个字符出现的次数:
#region 查询字符出现了几次
//===================================================
Dictionary<char, int> dict = new Dictionary<char, int>();
for (int i = 0; i < ziFu.Length; i++)
{
***&* 字符串可以当做字符数组来用!
????????????***&* ContainsKey(a)方法,使用来判断创建的字典集合中是否包含字符a;返回值为bool类型。
if (!dict.ContainsKey(ziFu[i]))
{
????????????***&* 调用字典集的Add方法,即其定义为:public void Add(TKey key, TValue value);
????????// key代表‘键‘,在这里代表字符,value 代表‘值‘ 在这里代表字符出现的次数!
dict.Add(ziFu[i], 1);
}
else
{
????????????***&* public TValue this[TKey key] { get; set; }
????????????//让字符出现的次数加1;
dict[ziFu[i]]++;
}
}
***&* KeyValuePair<> 称为键值对。
????????????//便利整个字典集,输出键值对的值!
foreach (KeyValuePair<char, int> i in dict)
{
Console.WriteLine("字符‘{0}‘,出现了{1}次", i.Key, i.Value);
}
//==================================================
#endregion
?
11.????去掉字符串中的空格:
?
string msg = " hello world 你好世界 ";
//因为Trim()有返回值,所以,必需接收返回值,否则,msg的是不会改变的!
//msg.Trim();//去掉两边的空格
msg = msg.Trim();
//以空字符为分隔符,然后移除空的字符串
string[] word = msg.Split(new[] {‘ ‘}, StringSplitOptions.RemoveEmptyEntries);
// RemoveEmptyEntries的意思就是:"返回值不包括含有空字符串的数组元素!"通过 StringSplitOptions 赛选留下自己需要的东西。
msg = string.Join(" ", word);
// Join 的意思是:"串联字符串中的所有元素,通过指定的字符来连接"
Console.WriteLine("=========" + msg + "==========");
?
12. ToLower()方法 即 "将字符串转化为小写形式"
例如:
Console.WriteLine(Name.ToLower())
?
将name全部转化为小写字符串。
13. 将字符串转化为字符数组:
char[] array = num.ToCharArray();
?
转化为字符数组是有必要的,如下:
String name="liqianlong";
//如果我要改变字符串中的一些字符,下面的做法是不正确的!
Name[2]=‘8‘;
但要是想取它的值,下面是合法的:
Char n=Name[2];
?
所以将字符串转化为字符数组是很有必要的!
14 . 通过索引来访问对象的字段值
在Main()方法里
ItcastClass ic = new ItcastClass();
for (int i = 0; i < ic.Count; i++)
{
Console.WriteLine(ic[i]);
}
在ItcastClass中:
public class ItcastClass
{
public int Count
{
get
{
return _name.Length;
}
}
private string[] _name = {"杨中科","蒋坤","赵鹏"};
//创建索引器
//索引器的特点为:
// 1. 没有具体的名称;
// 2. 就是特殊的属性;
// 3. 一个类中只有一个索引;
// 4. 索引可以重载;通过参数的不同,就可以将索引重载;
// 5.
public string this[int index]
{
get
{
return _name[index];
}
set
{
_name[index] = value;
}
}
}
15. 触发事件:
private void button1_Click(object sender, EventArgs e)
中的sender表示:"触发事件的控件";
EventArgs e 表示 :"事件的相关信息";
比如说:sender 代表 控件这个对象
E 代表 鼠标的操作等。
16. Base Class ->基类、 Parent Class ->父类
????Derived Class ->派生类 Child Class->子类
基类和父类的都属于父类
派生类和子类都属于子类
17. 调换两个数字【扩展】:
????Int a=10,b=15;
????A=a^b;
????B=a^b;
????A=a^b;
????Console.Writeline(a);
????Console.writeline(b);
18. 继承的特性:
1.单根性 – 一个类只有一个父类;
2. 传递性 – 属性或方法相传????
19. /*03----2013.06.01---基础加强--静态成员,静态类,静态构造函数,多态,里氏转换,抽象类实现多态,值类型余引用类型,值类型与引用类型作为参数传递时的问题,引用传递ref*/
????????1. 能够实现对字段友好的控制,从而增加安全性能。比如:
继承具有单根性、传递性。
2.1 如何实现多态:【通过虚方法实现多态】
在父类方法前面加上"Virtual"【将这个方法标记为虚方法】,然后继承该类的子类。如果你希望重写这个方法的话,那么就在这个方法前面写上Override。
注意:父类中的虚方法,子类可以重写也可以不重写。
所谓的重写就是:"子类中的方法名、返回值类型、参数类型及个数一定要相同。否则不能称作为重写。"
问题:
如果基类和子类都有一个同样的方法SayHi(),那么基类中的SayHi()方法前面必须加上Virtual,然后子类中的SayHi()前面必须加上Override,才算是将父类????中的方法进行覆盖。否则要是两个方法相同的话,就会有问题。然后要是在子类前面用new关键字,这样的作用就是将父类的方法隐藏。这样的话就不叫方法重写了。
通过上面的方法就可以达到隐藏父类中的方法,然后可以通过base.M1(),这样是调用父类的M1()方法。
里氏替换原则:
如果你需要一个父类类型时,给了你一个子类类型,也是可以的。
例如;
Person per=new Student();
注意:
当一个子类继承父类以后,该子类中的所有构造函数默认情况下,在自己调用之前都会先调用父类中的无参数的构造函数,如果此时父类中没有无参数的构造函数,则提示报错。
然后要想不让调用无参的构造函数,而去调用有参的构造函数,就这样做:
?
这里的【:base】的意思是调用父类中的构造函数。然后需要注意的是,构造函数是不能继承的。只能被调用。
这里应该注意的一点就是:"子类中想调用父类中的构造函数,那么子类中传入的参数的位置是可以随便排序的。"
同理,可以用this调用本类中的其他构造函数,这样减小代码的重复。
?
Public 任何地方都能访问到。
Internal 可以在整个程序集中访问。
Protected 在本类与子类中可以访问。
Private 在本类中可以访问到。
注意:在成员变量中,如果不写访问修饰符,那么就默认是private。而类的访问修饰符不写是internal.并且类的访问修饰符只能是public 和 internal。这只是对程序员进行限制的,而对于微软内部是可以使用其他修饰符的。
在子类中,使用this和base调用其成员变量时,实例化一个对象,然后先是去父类中调用父类的构造函数,然后在去调用自己的构造函数。调用父类的构造函数主要是对该对象的一些成员变量进行初始化,要是在自己的构造函数中再次初始化,这样只会对同一变量的值进行覆盖。
对于子类中继承下来的成员变量,不管是使用base还是this,都指的是同一空里的东西。而在这里注意:而对于继承下来的方法,如果子类重写了该方法,那么用base调用的是父类中的方法。如果不重写,就代表一个东西。
25.
Person p1=new Student();
Student s1=(Student)p1;
这样是可以的。
Person p2=new Person();
Student S2=(Student)p2;
这样是不可以的。
假如一个对象person[]数组,里面包含我们所知道的人,入"中国人"、 "美国人"等。然后让子类调用各自的SayHello()方法,然后就可以通过方法的重写或者方法的重载,来实现多态。
一般指方法的【名称】+方法的【参数列表】,不包含方法的返回值;类型。
30. 隐藏在父类中继承下来的方法或这属性:
用new 关键字:
如果子类中的方法与父类中的方法一样,但又不想重写该方法,那么就可以用new关键字解决。通过this调用这个方法,一定调用的是子类中的方法。但是如果用base调用调用这个方法,则调用的是父类中原来的方法。
????通过简单的例子来理解隐藏和重写的含义:
????假如有这么两个类:Persons和 Son
????????Public static void Main(string[] args)
????????{
????????????????Persons m1=new Son()
????????????????Son.SayHello();
}
然后如果Son重写了Persons类的方法SayHello(),通过上面的调用,调用的应该是Son类中的方法。如果是隐藏父类中的方法,那么通过上的方法调用,调用的是父类中的方法。
因此在访问静态成员的时候,不能通过对象来访问,(对象.属性名),只能通过"类名.属性名"来直接访问。
注意:在程序的任何地方访问静态成员时,都访问的是同一内存。
????在实例类中如果你操作的方法与对象无关的,那么这个方法就可以设置为静态方法。否则不能设置为静态方法。
在静态成员中存在的问题:静态成员为了能够在程序中的任何地方都能访问,它将在程序关闭之前不会被释放,直到程序关闭之后才被释放。而实例成员会在用完之后就会被回收。
当实例化对象的时候,可以通过调用该方法对该类进行实例化。
?
?
注意:既然访问修饰符不是你来去手动调用的,它是没有参数的。
????类中的静态成员,在第一次使用静态类的时候进行初始化。
静态构造函数只会被执行一次。是在第一次使用类或者是静态成员的时候执行。
然后如果一个类中即有实例类构造函数,还有静态类构造函数,他会去先执行静态的构造函数。然后再去执行实例类构造函数。这个具体的说明了之前的那句话:【静态构造函数会在执行类或者是静态成员的时候执行】
多态的作用:把不同的子类对象都当做父类来看待,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。、
实现多态的方式:
is-a:可以验证继承关系中是否合理。
If(obj is 类型A){} //obj是父类类型对象,"类型A"是子类类型。
Can-do:验证实现接口是否合理。
Person p=new Student();
Student s=p as Student;
如果转换成功,就返回Null,否则就返回这个对象。然后继续运行程序。
注意:它与强制类型转换的区别是:
强制类型转换时,当转换不成功就会报错。而使用这种方法是不会报错的。在这里建议使用这种方式。代码在执行过程中,使用这种方式效率比较高。
范例:public abstract void SayHi();
既然抽象与虚方法都能实现多态,那么如何去选择使用他们的呢?
注意:在开发项目中需要强调的一点是,能用抽象的,尽量用抽象的。
值类型:int 、char、double、float、long、short、byte、bool、enum、struct、decimal
注意:值类型都是派生自ValueType
值类型不能继承,只能实现接口。
引用类型:sting 、数组、类(子定义数据类型)、接口、委托、
Int[]n={1,2,3};//引用类型。
引用类型都派生自:Object
引用类型可以继承(类之间可以继承)
拾贝:内存里面我们分【栈】和【堆】
所谓的栈:在内存中连续的空间。栈中的内容进行拷贝的时候,都是复制一个数据副本。
所谓的堆:在内存中不连续的空间。
在这里之所以要强调堆和栈,是因为值类型分配的内存空间是固定的。即例如:char 类型占一个字节,就会在没存中开辟一个字节的空间,不管你用得到还是用不到。而引用类型就不一样了,它是根据数据大小而开辟的。
注意:一般传递都是值传递。即都是将数据拷贝了一份,然后进行操作。
@@***************** 08封装计算方法实现面向对象计算器 需要练习
43 . 引用传递:
//传的是栈本身的地址。。
前面加上ref时,如上例,通过M1函数传递m时,是将m所在的栈的地址给了n,即m和n就指向了同一个东西。
Out和ref 作用是一样的,但是你将数据传出去,而传不出来。即out只能传出去,不能传进来。
44. 方法重载【overload】和方法重写【override】
????区别一:
Overload 【重载】是在一个类中实现的方法的重载。
Override【重写】是子类与父类
????????????区别二:
方法重载是在编译期间就已经能够确定调用的是那个方法了。
而方法重写是在程序运行时才能够确定调用的是那个方法了。
????方法重载和返回值类型没有关系!只与参数的类型有关!参数的个数的不同也可以构成重载!
?
接口是以一种规范,协议(*),约定好遵守某种规范就可以写通用的代码。
例如:对于U盘来说:
接口是?
USB插口的标准就是一个接口
????????????在那个类中体现?
然后U盘实现了这样的接口。相当于他有了这样的功能。直白一点就是U盘符合USB插口的标准。
在哪里实现多态?
我的U盘可以用在各种各样的电脑上,或者支持USB接口的机器上。
定义了一组具有各种功能的方法。(只是一种能力,没有具体的实现,像抽象方法一样,"光说不做"【由具体的对象来实现。】和抽象类一样,里面的方法没有任何实现。)
即例子:
抽象类中的方法:
????Public void SayHello(); //里面不作任何处理。
44. 接口存在的意义:实现多态。
多态的意义:程序可扩展性。最终-》让程序变的更灵活,节省成本,提高效率。
45. 接口如何写?
定义接口用关键字interface 然后接口的名称一般以大写I开头。这样以后看见以I口头的关键词就知道是接口。最后都是以able结尾。
46. 接口里面的成员:
可以包含"方法"、"属性"、"索引器"、"事件"。但归根结底还是以方法的形式表现的。严格来说:只能包含方法。
注意:接口里面的所有成员都不能有显式访问修饰符。为了保证接口能够被实现,人家默认是public.方法里面不能包含任何实现。
可以有参数。
接口不能实例化。
接口中的成员,子类必须实现。
47. 实现多态:通过虚方法、抽象类或者抽象方法、还有就是接口。
48. 既然虚方法和抽象类都能多态,为什么还要引入接口?
????1. 对于类来说,继承具有单根性。那么有时候我想继承多个类咋办?那么就用接口。一个类只能继承一个父类,但可以实现多个接口。
????接口解决了单继承的缺点。
????2. 接口解决了不同类型之间的多台问题,不如说鱼和船不是同一类型,但是能在水里"游泳"。只是方式不一样,要对"游泳 "实现多态,就只能考虑接口。
这里注意:
如果即实现多个接口又要继承父类,那么,就必需将父类写在最前面,接口放在后面。
当父类和接口中有同名的方法,那么,就是显式接口。
49. 简单的实现接口程序:
????????namespace _002
{
class Program
{
static void Main(string[] args)
{
IConHomeWork conHomeWork=new Student();
conHomeWork.ConWork();
Console.ReadKey();
}
}
?
public interface IConHomeWork
{
void ConWork();
}
?
public class Student:Person,IConHomeWork
{
?
public void ConWork()
{
Console.WriteLine("学生收作业。");
}
}
?
public class Tearcher:Person,IConHomeWork
{
public void ConWork()
{
Console.WriteLine("老师收作业.");
}
}
?
public class SchoolMaster:Person
{
?
}
}
50. 对于一个普通的类来说,如果实现了一个接口,那么就要实现接口中的每一个成员,但对于一个抽象的类来说,可以不去实现它,让它的子类去实现这个方法。
51. 显示实现接口:【就是为了解决方法名重名的问题】
【当方法命名重名的时候,才会用到显示实现接口。】
????比如说:有一个类实现了两个接口,恰巧两个接口中都有一个SayHello()方法。然后这个类实现接口中的方法后,这个类中就有两个SayHello()方法,然后就不好确定哪个方法是实现那个接口的。
注意:类或者接口中前面如果没有访问修饰符时,那么就默认为internal。然后当你写一个类继承或者实现某个接口的时候,就会出现提示信息,然后提示信息对应的前面会有一个小信封图标。如下图:
对于是internal类,前面的图标为:
对于是internal接口,前面的图标为:
52. 小错误:
由于子类中访问修饰符大于父类中的访问修饰符,所以会报错。
53. 接口总结:
????·接口是一种规范。为了多态。
????·接口不能被实例化。
????·接口中的成员不能加"访问修饰符",接口中的成员访问修饰符为public,不能修改。(默认为public)
????·接口中的成员不能有任何实现("光说不做",只是定义了一组为实现的成员。)
????·接口中只能有方法、属性、索引器、事件,不能有字段。
????·接口与接口之间可以继承、并且可以多继承。
????·实现接口的子类必须实现该接口的全部成员。
????·一个类可以同时继承一个类并实现多个接口,如果一个子类同时继承父类A,并实现了接口IA,那么语法上A必须写在IA的前面。class MyClass:A,IA{},因为类是单继承的。
????·当一个抽象类实现接口的时候,如果不想把接口中的成员实现,可以把该成员实现为abstract。(抽象类也能实现接口,用abstrac标记。)
????·"显示实现接口",只能通过接口变量来调用(因为显示实现接口后成员为private)。
54. 使用接口的建议:
????·面向对象编程,使用抽象(父类、抽象类、接口)不使用具体实现。
????·"向上转型"
????·在编程时:
????????·接口-》抽象类-》父类-》具体类(在定义方法参数、返回值、声明变量的时候能用抽象就不要用具体。)
????????·能使用接口就不用抽象类,能使用抽象类就不用类,能用父类就不用子类。
????????·避免定义"体积庞大的接口"、"多功能接口",会造成"接口污染"。只把相关联的一组成员定义到一个接口中(尽量在接口中少定义成员)。单一职责原则。
????????·定义多个职责单一的接口(小接口)(组合使用)。(印刷术与活字印刷术)????
55. 在C#中,switch-case中的break不能缺少,但在java中是可以缺少的。
56. 方法的总结:
????·对于一个方法本身来说,它不可以自己调用自己。因为这样会导致内存溢出。程序会不停的调用自身的方法,没有结束语句。
????·对于一个有返回值的方法来说,我可以定义一个变量来接收,也可以不去接收它的返回值。程序运行的时候是不会报错的。
57. 数据类型转换:
1. 隐式类型转换:
????·源数据类型小于目标类型;
????·一般用于数值类型。
注意:在int 、char 、byte、short、long之间也是可以进行转换的。可以这样理解,其实char类型本质是数值类型的。
58. 通过sizeof(类型)可以求出类型所占用的字节数。
59. 获取一个成员的类型:
基本语法为:
????·成员名.GetType().ToString(); //得到成员的类型。
????·成员名.GetType().BaseType().ToString(); //得到成员的父类类型。
????·成员名.GetType().BaseType().BaseType().ToString() //得到成员的父类的父类类型。
如下图所示:
注意:使用这种方法的弊端是:如果已经到了最终的父类后,还要找它的父类,那么程序就会报错。
????所以,一般情况下我们不建议使用这种方式。我们可以使用as来判断成员的类型是什么。。
as 的使用:
比如说有:一个Person类、Student类、BestStudent类,然后student继承自Person类、BestStudent继承自Student类。
如下图所示:
????
对于上面的代码,如果p是BestStudent那么就会 对于这个问题,百度as的作用。没听懂。
60. 异常处理1:
·捕获异常机制:
????try
{????
????//可能发生异常的代码。
}
catch
{????
????//发生异常的最后的处理。
????throw;//处理完成异常之后,要对上报异常。用throw就是继续处理异常。
}
finally
{????
????//无论发不发生异常,都一定要执行的代码。
}
????注意:一个try块可以跟一个或者多个或0个catch块,后面跟finally也行不跟也行。finally只能有一个。
·当你让屏幕显示异常,那么就如下这样写:
????try{}
????catch(Exception ex)
{
Console.WriteLine(ex.Message) //显示异常的信息。
Console.WriteLine(ex.Source); //显示异常发生在那个命名空间里面
Console.WriteLine(ex.StackTrace); //显示异常的跟踪信息,具体显示异常发生在哪一行的代码中。
}
????finally{}
这样就可以将出现的异常显示在屏幕中。
·catch中的几种写:
????try{}
????//当出现空指针异常的时候,就会走这里。
????catch(NullReferenceException ex){}
????//当出现除数为0的时候,就会走这里。
????catch(DivideByZeroException ex){}
????//当出现参数异常的时候,就会走这里。
????catch(ArgumentException ex){}
????//当出现其他异常的时候,就会走这边。
????catch(Exception ex){};
注意:不要将catch(Exception ex){};放在最前面,因为这句话是接收所有异常的,所以当放在最前的,出现异常时就会走这句话,其他catch是不会走的。
61. 异常2:
????要是想让代码不论任何情况下,代码都能够执行。就要用finally语句。有的时候,不用finally,而且还想让catch后面的语句执行时,有些情况是不允许的。例如:
·catch中如果有return时且出现异常,那么就不会执行后面的代码了,但是当你将代码放在finally中,就可以让这段代码执行。
·当catch有无法捕获到的异常时,程序崩溃,但在程序崩溃前会执行finally中的代码,而finally块后的代码则由于程序崩溃了无法执行。
62. 异常3:【手动引发异常】
例如:
????static void Main(string[] args)
{
while (true)
{
Console.WriteLine("请输入一个人的年龄?");
string name = Console.ReadLine();
try
{
if (name == "黄林")
{
throw new Exception("年龄不合法!");
}
else
{
Console.WriteLine("合法姓别!");
}
}
catch (Exception ex)
{
?
Console.WriteLine(ex.Message);
Console.WriteLine(ex.StackTrace);
}
}
}
63. 异常4:
对于上面的例子,M2调用M1,然后又在Main方法中调用, 然后通过throw,将当前的异常继续向上抛出。。
注意:M2的处理代码如下:
????try
{
????M1();
}
catch
{
????Console.WriteLine("M1放噶中发生异常了。");
throw;???? //继续向上抛出异常。
}
注意:一般不要用抛出异常的方式来,而应该给用户输入一句话来提示用户。
64.加强:
????private static int M1()
{
int result = 100;
try
{
result++;
return result;
}
catch
{
result++;
return result;
}
finally
{
Console.WriteLine("==================");
result++;
}
}????????
注意:根据提示可知,针对上段代码,先走的是try里面的,然后已经将return执行完成之后,然后再执行finally里面的代码。
即这段代码的本质是如下图:
????
注意看图片上面的返回值,他返回的是而不是result.之所以会自动添加变量
,是因为编译器在返回值的时候,会给你自动声明返回值变量,然后当程序员return 的时候,其实返回的时候并不是你指定的变量,而是编辑器自动生成的变量。
还有一种情况就是:对于上面的int result是值类型,而对于引用类型来说,结果就不一样了。
例如:
private static int M1()
{
????????Person per=new Person();
????????per.Age=100;
try
{
per.Age++;
????????????【中间出现异常代码省略】
return p;
}
catch
{
per.Age ++;
return p;
}
finally
{
Console.WriteLine("==================");
per.Age++;
}
}????????
通过反编译来看:
????
然后在调用的时候,结果是:
????·不出现异常是:102;
????·出现异常是:103;
????
65. 参数:
????可变参数:
????在定义的时候,用数组来表示。具体形式表示为:
????void 方法名(params int[] args);
????注意的事项:
????1. 如果方法有多个参数,可变参数必须作为最后一个参数。
????2. 可变参数可以传递参数也可以不传递参数。如果不传递参数,则数组args[]是一个长度为0的数组,而不是null;
????3. 可变参数可以直接传递一个参数。
????4. 也可以传递一个null过去。所以到你想用数组args[]时,就必需判空。
66. out – ref
方法的重载中不支持out和ref的,也就是说,只有out 和 ref 的区别是构成不了重载的。
例如:
void SayHello(ref string name)
{
}
voi SayHello(out string name)
{
}
这样子是构成不了重载的,程序是不支持的。因为它们大体上的作用是一样的。
67. 比较两个对象是否为同一对象:
方法一:
????使用object.ReferenceEquals(对象一,对象二); 注意返回值类型为bool类型。
方法二:
????对象名.Equals(对象二); 有返回值,返回值类型为bool 类型。
方法三:
????使用等值语句:
????例如:if(p1==p2)
????????{
????????????Console.WriteLine(true);
}else
{
????Console.WriteLine(false);
}
整套代码如下:
????static void Main(string[] args)
{
Person p1=new Person();
p1.Name = "liqianlong";
p1.Age = 21;
p1.Sender = ‘男‘;
?
Person p2=new Person();
p2.Name = "liqianlong";
p2.Age = 21;
p2.Sender = ‘男‘;
?
Person p3 = p1;
?
//比较两个对象是否为同一对象。
Console.WriteLine(object.ReferenceEquals(p1,p2)); //False
Console.WriteLine(object.ReferenceEquals(p1,p3)); //true
?
Console.WriteLine(p1.Equals(p2)); //False
Console.WriteLine(p1.Equals(p3)); //true
if (p1 == p3) //true
{
Console.WriteLine(true);
}
else
{
Console.WriteLine(false);
}
Console.ReadKey();
}
?
标签:
原文地址:http://www.cnblogs.com/taidou/p/4673664.html