C#是面向对象的语言,在面向对象的思想中,只有对象,所有事物都可以用类描述。所以比如这些,int,bool,char,string,double,long等都是类,那么像,30,2.5,"test"都是对应类的一个对象。
static void Main(string[] args)
{
string istring = 30.ToString();
string dstring = 2.5.ToString();
string sstring = "test".ToString();
Console.WriteLine(string.Format("{0},{1},{2}", istring, dstring, sstring));
Console.ReadLine();
}
输出:
可以看出它们有ToString()这个方法,所以它们是对象。
在平时写代码时,定义数据类型除了上述的这种之外,肯定都用过:
static void Main(string[] args)
{
Int32 i = 0;
UInt32 j = 0;
String str = "test";
Console.ReadLine();
}
这个其实是.NET的一个机制,.NET是一个平台,这个平台上有C#,VB这些语言。因此,.NET定义了一系列类型,映射到不同的语言中,Int32在c#中就是int。这样的数据类型称作基元类型,在C#中类的对象必须使用new生成。而这一部分类直接就可以用常量表示。基元类型定义在.net Framework中,System命名空间下。看一下基元类型在C#语言中的类型映射。
.NET Framework基元类型
|
C#类型
|
取值范围 |
备注 |
System.Boolean
|
bool
|
true/false |
/ |
System.Byte |
byte |
0 ~255 |
无符号8位整数
|
System.Sbyte |
sbyte |
-128 ~ 127 |
有符号8位整数 |
System.Char |
char |
0 ~ 65,535 |
无符号16位整数 |
System.Int16 |
short |
-32,768 ~ 32,767
|
有符号16位整数 |
System.UInt16 |
ushort |
0 ~ 65,535 |
无符号16位整数 |
System.Int32 |
int |
-2,147,483,648 ~ 2,147,483,647 |
有符号32位整数 |
System.Int64 |
long |
-9,223,372,036,854,775,808 ~
9,223,372,036,854,775,807
|
有符号64位整数 |
System.UInt64 |
ulong |
0 ~ 18,446,744,073,709,551,615
|
无符号64位整数 |
System.Single |
float |
±1.5 × 10-45 ~ ±3.4 × 1038
(7位有效数字)
|
32位单精度浮点数 |
System.Double |
double |
±5.0 × 10-324 到 ±1.7 × 10308
(15至16位有效数字)
|
64位双精度浮点 |
System.Decimal |
decimal |
±1.0 × 10-28 到 ±7.9 × 1028
(27至28位有效数字)
|
128位浮点数数 |
System.String |
string |
任意字符串 |
/ |
System.UInt32 |
uint |
0 ~ 4,294,967,295 |
无符号32位整数 |
表中的除了string是引用类型(后面单独解释),其它都是值类型。
下面简单介绍下引用类型和值类型。
学习C语言的时候有个堆和栈的概念。
堆区——程序员分配释放,或者程序结束有OS回收,分配方式类似于链表。
栈区——由编译器自动分配释放,存放函数的参数值,变量值等。
栈内存结构可以快速的分配内存和回收内存,但栈空间有限,过多使用会“溢出”,因此栈只分配常用的,占用空间小的数据类型;堆内存结构分配内存较慢,但是利用空间大,可以存放大型数据。
在C#中,基本上所有的数据都存储在“堆”结构中,称之为“托管堆”,受.NET垃圾回收监控。但是相对于栈堆结构中内存分配效率比较低。为了正确进行垃圾回收,每次分配的堆空间比实际所需空间稍大,小型数据使用堆是不太合适的。
可以比较看一下值类型和引用类型:
C#中提供了Struct定义值类型,直接在栈上分配内存。
/// <summary>
/// 使用struct定义一个值类型,
/// 值类型的只能实现接口,不能继承类
/// </summary>
public struct StructPositiveNumber : ICloneable
{
/// <summary>
/// 值类型字段
/// </summary>
private int number;
/// <summary>
/// 静态只读字段,作为类的初始值
/// </summary>
public readonly static StructPositiveNumber InitialValue = new StructPositiveNumber();
/// <summary>
/// 属性
/// </summary>
public int Number
{
get
{
return number;
}
set
{
if (value <= 0)
{
throw new Exception();
}
this.number = value;
}
}
/// <summary>
/// 可以定义构造器,但是和类不同,这里的默认构造器依然存在
/// </summary>
public StructPositiveNumber(int value)
{
if (value <= 0)
{
throw new Exception();
}
this.number = value;
}
/// <summary>
/// 实现克隆方法,返回当前对象
/// </summary>
/// <returns></returns>
public object Clone()
{
return new StructPositiveNumber(this.number);
}
}
调用
static void Main(string[] args)
{
//声明变量,赋值
StructPositiveNumber pNumber1 = StructPositiveNumber.InitialValue;
pNumber1.Number = 1;
//pNumber1赋给pNumber2
StructPositiveNumber pNumber2 = pNumber1;
//改变pNumber2的值
pNumber2.Number = 2;
//看打印结果,改变了pNumber2的值,但是不影响pNumber1
Console.WriteLine(pNumber1.Number);//1
Console.WriteLine(pNumber2.Number);//2
//重新初始化pNumber2,通过构造器生成改变了初始值。
pNumber2 = new StructPositiveNumber(3);
Console.WriteLine(pNumber2.Number);//3
//调用Clone将pNumber2复制给pNumber1
pNumber1 = (StructPositiveNumber)pNumber2.Clone();
Console.WriteLine(pNumber1.Number);//3
//改变pNumber1的值,但是pNumber2值不改变
pNumber1.Number = 4;
Console.WriteLine(pNumber1.Number);//4
Console.WriteLine(pNumber2.Number);//3
Console.ReadLine();
}
结果
再看引用类型定义的:
public class ClassPositiveNumber : ICloneable
{
private int number;
public int Number
{
get
{
return this.number;
}
set
{
if (value <= 0)
{
throw new Exception();
}
this.number = value;
}
}
//引用类型自己可以初始化为null,无需定义初始值
//public readonly static ClassPositiveNumber InitialValue = new ClassPositiveNumber();
public ClassPositiveNumber(int value)
{
if (value <= 0)
{
throw new Exception();
}
this.number = value;
}
public object Clone()
{
return new ClassPositiveNumber(this.number);
}
}
调用
static void Main(string[] args)
{
ClassPositiveNumber cNumber1;//默认值为null
cNumber1 = new ClassPositiveNumber(1);
ClassPositiveNumber cNumber2 = cNumber1;
cNumber2.Number = 2;
//可以看出,两个引用引用到了相同的对象
Console.WriteLine(cNumber1.Number);//2
Console.WriteLine(cNumber2.Number);//2
//重新初始化cNumber2,之前的对象已被丢弃
cNumber2 = new ClassPositiveNumber(3);
Console.WriteLine(cNumber2.Number);//3
//复制是复制一个对象的副本,因此,是两个不同的对象
cNumber1 = (ClassPositiveNumber)cNumber2.Clone();
Console.WriteLine(cNumber1.Number);//3
cNumber1.Number = 4;
Console.WriteLine(cNumber1.Number);//4
Console.WriteLine(cNumber2.Number);//3
Console.ReadLine();
}
结果
通过例子,可以看出值类型的特点如下:
a、使用struct声明;
b、不能继承类,但是可以实现接口(当然除object类外);
c、值类型使用值类型做为字段,但是字段无法有默认值;
c、值类型中必须有默认构造器,而且自己定义构造器后,默认的无参数的构造器依然存在。而且在构造其中只能访问类中的字段,但是不能访问属性。符号=对于值类型来说是赋值,所以赋值是值类型变量不能为空,因为值类型没有引用的概念,肯定有值。
代码下载:http://download.csdn.net/detail/yysyangyangyangshan/4452051
分享到:
相关推荐
c#基础知识 c #基础知识 c#基础知识
C#中引用类型和值类型的区别C#中引用类型和值类型的区别
C#基础知识C#基础知识C#基础知识C#基础知识
一起回忆那些年美好的回忆吧,缅怀青春,昂首迎接新的挑战,我们可以走的更远!
理解C# String类型:特殊的引用类型
C#基础知识:入门与提高的最佳资料! 主要介绍了C#语言基础、Windows编程的基础知识、常用控件和类的使用等!
C#基础知识思维导图(整理版),较之前的版本,进行了一些整理
C#基础知识C#基础知识C#基础知识C#基础知识
对于已经有C#开发知识的研发人员的基础知识进行巩固,比较好的全面过滤。
c# 值类型 引用类型 内存分析 图解 ,从根本上理解值类型和引用类型变量的本质区别。
01c#基础知识 02c#入门 03编写c#表达式
C#中除了基本类型以外的类型都是引用类型。引用类型的特点是,在堆栈中存储的是该引 用类型指向的堆中的“地址”。所以,当引用类型之间相互赋值的时候,只是将堆栈中的值 (可以理解为所指向的“堆”地址)相互赋值...
C#基础知识点.doc
C#基础知识.doc C#基础知识.doc C#基础知识.doc C#基础知识.doc C#基础知识.doc
c#基础知识点大全,分条总结。另附winform,css,HTML知识点
C#语言基础知识点大全分享C#语言基础知识点大全分享C#语言基础知识点大全分享C#语言基础知识点大全分享C#语言基础知识点大全分享C#语言基础知识点大全分享C#语言基础知识点大全分享C#语言基础知识点大全分享C#语言...
温故而知新可以为师矣,牢固的基础能支撑我们前进的更远!
C#基础知识教程下载,简单实用,值得初级人员学习参考
c# 基础知识中的一些小知识点,如REF,OUT关键字,类型推断等等。
提供C#基础知识的系统整理,应对期末考试有帮助。