*值类型:栈 引用类型:堆
*值类型struct :不支持终结器。
struct Angle
{
//构造器,在struct中禁止默认(无参数)的构造器
public Angle(int hour, int minute, int seconds)
{
_Hours = hour;
_Minutes = minute;
_Seconds = seconds;
}
//bixudui struct中的所有字段初始化,而不是属性。
// public Angle(int hour, int minute, int seconds)
// {
// Hours = hour;
// Minutes = minute;
// Seconds = seconds;
// }
//属性
public int Hours
{
get
{
return _Hours;
}
}
private int _Hours; //字段,结构中不能有实例字段初始值,区别于类。
public int Minutes
{
get
{
return _Minutes;
}
}
private int _Minutes;
public int Seconds
{
get
{
return _Seconds;
}
}
private int _Seconds;
//方法
public Angle Move(int hours, int minutes, int seconds)
{
return new Angle(Hours+hours,minutes+Minutes,Seconds+seconds);
}
}
class Coordinate
{
public Angle Longitude
{
set; get;
}
public Angle Latitude
{
get;set;
}
}
**default运算符的使用
//用default运算符来获取某个类型的默认值。
//用this调用构造器
public Angle(int hour, int minute):this(hour,minute,default(int))
{
}
*值类型的继承和接口:只有值类型都是密封的,派生自System.object-->System.ValueType
(下面的还没有理解:)
对于值类型来说,getHashCode()的默认实现是将调用转发给struct中的第一个非空字段。
Equals()大量利用了反射机制。假如一个值类型在集合中频繁使用,尤其是使用了散列码的字典类型的集合,那么值类型应该同时包含对Equals()和GetHashCode()的重写。
*装箱(boxing):值类型向引用类型转型。相反的过程叫做拆箱(unboxing)。
int number;
object thing;
number = 43;
//boxing
thing = number;
//unboxing
number = (int)thing;
*容易被忽视的装箱和拆箱过程
class Program
{
static void Main(string[] args)
{
int totoalCount;
System.Collections.ArrayList list = new System.Collections.ArrayList();
Console.Write("enter a number between 2 and 1000:");
totoalCount=int.Parse( Console.ReadLine());
//list.Add(object value)传给该方法的任何类型都会被装箱。
//如果只是list.Add(0),下面list[count - 1] + list[count - 2]会造成两个object相加,编译错误。
list.Add((double)0);
list.Add((double)1);
for (int count = 2; count < totoalCount; count++)
{
//unboxing的过程
list.Add((double)list[count - 1] + (double)list[count - 2]);
}
foreach(double count in list)
{
Console.Write("{0}, ",count);
}
Console.ReadKey();
}
}
*必须拆箱为基础类型
int number;
object thing;
double bigNumber;
number = 43;
//boxing
thing = number;
//unboxing
number = (int)thing;
// bigNumber = (double)thing;
//上面的语句引发一个invalidCastException错误
bigNumber = (double)(int)thing;
*lock语句中的值类型(没接触过)
System.Threading.Monitor:Enter() Exit() 不允许lock语句中只用值类型。因为值类型的问题在于装箱,每次调用Enter()或者Exit()的时候,都会在堆上创建一个新值。将副本的引用与另一个不同副本的引用进行比较,总是返回false。
*避免拆箱和复制
int number;
object thing;
string text;
number = 43;
//boxing
thing = number;
//unboxing
number = (int)thing;
text = ((IFormattable)thing).ToString();//使用接口来避免拆箱
*值类型enum(System.Enum):枚举,默认第一个数是0,也可以自己指定。基础类型可以是int ,uint,long,ulong
*枚举之间的类型兼容性:c#不支持不同的枚举数组之间的直接转型。一个办法是可以强制实现两者之间的转换,办法是先转型为一个数组,在转型为第二个枚举类型。同时,要求两个枚举类型具有相同的基础类型,而且必须先转型为System.Array。
class Program
{
static void Main(string[] args)
{
ConnectionState1[] states = (ConnectionState1[])(Array)new ConnectionState1[42];
//下面这句也没有(Array),也没有报错,不是很理解,隐式转换?。
ConnectionState1[] states1 = (ConnectionState1[])new ConnectionState1[42];
}
}
enum ConnectionState1
{
Disconnected,
Connecting,
Connected,
Disconnecting
}
enum ConnectionState2
{
Disconnected,
Connecting,
Connected,
Disconnecting
}
**枚举和字符串之间的转换
Console.WriteLine(string.Format("{0}",ConnectionState1.Disconnected));
Console.WriteLine( (ConnectionState1.Disconnected).ToString());
Enum.Parse();
Enum.TryParse();
**FlagAttribute