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의 메커니즘입니다. 이 플랫폼에는 C#, VB와 같은 언어가 있습니다. 따라서 .NET은 다양한 언어에 매핑되는 일련의 형식을 정의합니다. C#에서는 int입니다. 이러한 데이터 유형을 기본 유형이라고 합니다. C#에서는 new를 사용하여 클래스 개체를 생성해야 합니다. 클래스의 이 부분은 상수로 직접 표현될 수 있습니다. 기본 유형은 .net Framework의 System 네임스페이스 아래에 정의됩니다. C# 언어에서 기본 유형의 유형 매핑을 살펴보세요.
.NET Framework 기본 유형 | C# 유형
| 값 가져오기 범위 | 비고 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Boolean <🎜> | 부울<🎜> | 참/거짓 | / | < /tr>||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
System.Byte | byte | 0 ~255 | <🎜>부호 없는 8비트 정수<🎜>< / td> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
System.Sbyte | sbyte | -128 ~ 127 | 부호 있는 8비트 정수 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
System.Char | char | 0 ~ 65,535 | 부호 없는 16비트 정수 | tr >||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
System.Int16 | short | <🎜>-32,768 ~ 32,767<🎜> | 부호 있는 16비트 정수 td > | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
System.UInt16 | ushort | 0 ~ 65,535 | 부호 없는 16비트 정수 | < / tr>||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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 < /sup> ~ ±3.4 × 1038<🎜><🎜>(유효 숫자 7개)<🎜> | 32비트 단정밀도 부동 소수점 수 | < /tr>||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
System.Double | double | <🎜>±5.0 × 10-324 ~ ±1.7 × 10< sup >308<🎜><🎜>(유효 숫자 15~16자리)<🎜> | 64비트 배정밀도 부동 소수점 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
System.Decimal | decimal | <🎜>±1.0 × 10-28 ~ ±7.9 × 1028<🎜 > <🎜>(유효 숫자 27~28개)<🎜> | 128비트 부동 소수점 수 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
System.String | 문자열 | 모든 문자열 | / | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
System.UInt32 | 단위 | 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、值类型中必须有默认构造器,而且自己定义构造器后,默认的无参数的构造器依然存在。而且在构造其中只能访问类中的字段,但是不能访问属性。符号=对于值类型来说是赋值,所以赋值是值类型变量不能为空,因为值类型没有引用的概念,肯定有值。
以上就是C#基础知识整理:基础知识(11) 值类型,引用类型的内容,更多相关内容请关注PHP中文网(www.php.cn)!