c#入门-objtct的方法

声明类型的基类

c#中的类都继承自object类,包括静态类。
静态类只是无法手动指定继承类型,而声明静态类时的关键字class,已经让他派生自object类了。

结构类型继承自ValueType类,而ValueType继承自object类。
数组继承自Array类,Ayyar类继承自object类。

c#中几乎所有类型都继承自object类。
大多数没有继承object类型的类都是作为变量时声明的类型,
例如接口,例如泛型占位符。
这些类型都是使用特殊手段翻定义才翻出来他们的根本没有到object的继承关系。
这种东西不重要,只是编译阶段的类型,不是运行阶段的类型。他们是可以赋值给object类型的变量的。

而无法赋值给object的值,目前我只找到指针类型。
在这里插入图片描述

object的方法

既然几乎所有类型都继承自object,那么我们应该了解一下object的方法。

ToString

这个方法决定了一个类如何转为字符串。
这是一个虚方法,你可以自己决定如何实现它。
他的默认实现是输出GetType的ToString。也就是直接输出类型的完全限定名。

class Fight
{
	public int Hp;
	public int Atk;
	public int Def;
	public override string ToString()
	{
		return $"HP:{Hp},Atk:{Atk},,Def:{Def}";
	}
}

Equals

Equals是一个相等判断的方法,用于判断目标值和自己是否一样。
这个方法和==有什么区别,区别是他们就是两个东西。

你可以重写并利用Equals方法,也可以重载并使用==进行判断。
在一般情况下,只会编写其中一种方法,而另一种方法会直接调用编写好的方法。

在模式匹配和查询表达式中,使用is和equals关键字。
这个的意义是告诉你,你重写的东西没用。我要把他以object的Equals进行判断。

另外,在ValueType类型中,Equals方法被重写了。
他会先判断自己和目标类型是否一样,然后使用反射判断所有的字段是否一样。
反射是非常消耗性能的,所以在声明结构的时候,建议重写Equals方法。

class Fight
{
	public int Hp;
	public int Atk;
	public int Def;
	public override bool Equals(object obj)
	{
		return obj is Fight other 
			&& Hp == other.Hp 
			&& Atk == other.Atk
			&& Def == other.Def;
	}
}

GetHashCode

这个方法决定了一个类如果获取他的哈希值。也是一个虚方法。
哈希值是一个普通的int类型。任何类都可以转为string,那要求任何类都可以转为int也很合理吧。

哈希值算是一种特征码。一个类有不同值的时候,结果尽量不同。
并且如果一个类在Equals判断为相等时,要求得到同样的哈希值。

并且尽量均匀覆盖所有的int。
比如记录人的生日取哈希值的时候,如果取年份那就补不均匀了。
活着的人全挤在1900-2100之间。并且1980-2010之间的数字特别多。

如果取月份,那就有点均匀了。但月也有大月和小月的区分,特别是2月最少。
所以,这个方法对怎样取值没用硬性规定。你应该结合你的类的字段,自己做出判断。

GetType

GetType不是虚方法,不能重写。
这个方法用于获得在反射时使用的,类的类型。
反射大致是一种让已经编译好的程序,回过头来看源码的功能。
但只能看到类成员的声明和定义。

而GetType就是看到这个类型的定义。
这个方法不能重写所以不会骗人。

例如有一种声明类型的方法是这样的

using System.Security.Cryptography;
MD5 md5= MD5.Create();

他不使用传统的new MD5()构造器的方式。
如果使用构造器那一定会得到MD5类型。

但使用静态方法就不一定了。他可能先调用了new MD5,
然后改了一些值。如果无法成功就给你一个null。
又或者他挑了一个继承自MD5的派生类,用多态的方式假装给你一个MD5。

Console.WriteLine(md5.GetType().Name);

用GetType可以看到他真正的类型,果然不是MD5。

MemberwiseClone

这个方法是一个protected方法,不能被外部调用。他也不能被重写,只是给你用的。
他的效果是获取当前类的浅拷贝,然后把这个复制的新对象给你。
不过由于是在object里声明的,而且不能重写,所以返回类型是object。
但放心,返回的值就是你这个类的类型,安心强转他。

class Tesk
{
	public Tesk Clone()
	{
		return (Tesk)MemberwiseClone();
	}
}

所谓浅拷贝,是指把所有字段全都复制一遍。
而我们说过,引用类型只是复制的话会窜号。
引用类型保存的是他的地址,或者说快捷方式。两份快捷方式打开的是同一份内容。

而深拷贝就是在遇到引用类型时递归这个过程,把引用类型也浅拷贝,如果里面还有引用类型继续浅拷贝。
这样一来,引用类型的内容和原来的内容一样,但不会窜号了。
但这个过程太过复杂,也只能用反射操作性能也低。
甚至要考虑出现循环引用的时候会不会出现bug。所以没给深拷贝的方法。

另外,值类型在赋值的时候,可能就是在自动调用这个方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值