C#的类型、变量和值

大学学了C#,工作也是使用C#,虽然在日常的开发中没什么大的问题,但个人觉得在C#的理解还不是很清晰,所以决定花一定的时间来理一理学过的知识,顺便革新下脑袋里的知识,因为坑爹的学校在教.net的时候,是.net 2.0版本的,有点老古董了。哎,个人觉得是老师只会拖控件,而且对于新的.net版本他们应该很难去接受,所以挑选教材的时候,也不愿意去挑选自己不熟悉的新的.net版本。好了,也不吐槽学校和老师了,还是自己努力吧,因为老师毕竟教你了他们知道的。

1,类型

C#是一种强类型的语言。每个变量和常量都有一个类型,每个计算为值的表达式也是如此。 每个方法签名为每个输入参数和返回值指定一个类型。 .NET Framework 类库定义了一组内置数值类型以及表示各种逻辑构造的更复杂的类型,例如文件系统、网络连接、对象的集合和数组及日期。 典型 C# 程序使用类库中的类型,还使用为特定于该程序问题域的概念建模的用户定义类型。

思考一下,类型是干什么用的。其实不难发现,我们总是把我们需要的东西存储在用类型定义的变量上,如 int i=1,我们就把1存储在i变量所在的存储空间里,所以类型就是用来存储信息的。

类型可以存储的信息包括

  • 该类型的变量所需的存储空间。
  • 该类型可以表示的最大值和最小值。
  • 该类型包含的成员(方法、字段、事件等)。
  • 该类型所继承的基类型。
  • 将在运行时为其分配变量内存的位置。
  • 允许的运算种类行

当然我们使用类型的时候,是通过编译器,编译器为什么能够执行,是因为执行的代码是安全的,那么编译器是怎么确保执行的代码是类型安全的?例如,我们不可能把一个boolean类型的数据赋值给一个int类型的数据。这就可以想到:类型是存储信息的,所以编译器是通过类型存储的信息确保代码中执行的所有运算都是类型安全的。

其实编译器将类型信息作为元数据嵌入到可执行文件中。 公共语言运行时 (CLR) 会在运行时使用该元数据,以进一步确保它在分配和回收内存时类型安全。

2,在变量中声明指定的类型

在程序中声明变量或者常量的时候,必须指定类型或者使用关键字var让编译器可以识别到其类型。如下使用了一些类型和自定义的类型

Codefloat temperature;//float类型
string name;//string类型
MyClass myClass;//自定义类型

char firstLetter = ‘C‘;//char类型
var limit = 3;//var 定义的object类型,可千万别单纯的认为这个是int类型
int[] source = { 0, 1, 2, 3, 4, 5 };//数组,引用类型

在程序中,类型可以在方法参数和指定返回值中使用,看下面代码传入参数定义为了int类型,返回值是string类型

Codepublic string returnValue(int id){
   return id+"";
}

声明了一个变量后,不能使用新类型重新对它进行声明,也不能向它赋与它的声明类型不兼容的值。例如,不能声明 int,然后向它赋予布尔值 true。 但是,值可以转换为其他类型,例如将值赋给新变量或者作为方法参数传递时。 编译器会自动执行不会导致数据丢失的类型转换。 可能导致数据丢失的转换需要源代码内有强制转换。

2,内置类型

C#提供了一组标准的内置数值类型,用来表示整数、浮点值、布尔表达式、文本字符、十进制数值和其他类型。还有内置的string和object类型。我们可以在c#程序中可以很方便的使用这些类型

3,自定义类型

我们可以使用struck、class、interface和enum来创建我们自己自定义的类型。NET Framework 类库本身是 Microsoft 提供的自定义类型的集合,您可以在自己的应用程序中使用它们。 默认情况下,类库中最常用的类型在所有 C# 程序中均可用。 而对于其他类型,则仅当您显式添加定义这些类型的程序集的项目引用后它们才可用。 编译器拥有对该程序集的引用后,才可以在源代码中声明在该程序集中声明的类型的变量(和常量)

4,通用类型

(1)值类型

值类型派生自System.Object和System.ValueType.派生自 System.ValueType 的类型在 CLR 中有特殊行为值类型变量直接包含它们的值,这意味着内存在声明变量的任意上下文中都是以内联方式分配的。 值类型变量没有单独的堆分配或垃圾回收开销。

值类型分为两个类别:struct和enum。

内置值类型具有可以访问的属性和方法。如 byte b=Byte.MaxValue。我们也可以向值类型赋值,如int i=1;

我们也可以使用struct来创建自己的自定义类型。如

Codepublic struct Person{
  int x;
  int y;
  public int say(int parms1,int parms2){
     return parms1+parms2;
   }
}

我们可以使用enum来定义一组常量,如

Codepublic enum number{1,2,3}

枚举类型主要是用来限制变量的可能性,如我们上面定义了枚举number,包含了123,三个int型,在使用number时,只能使用这3个数,不可能出现其他的数。

(2)引用类型

定义为类、委托、数组或接口的类型是引用类型.在运行时,当您声明引用类型的变量时,该变量会一直包含值 null,直至您使用 new 运算符显式创建对象的实例,或者为该变量分配已经在其他位置使用 new 创建的对象, 如

CodePeroson p1=new Person();
Person p2=p1;

接口必须与实现它的类对象一起初始化

创建对象时,将在托管堆上分配内存,变量只保存对对象位置的引用。对于托管堆上的类型,在 CLR 的自动内存管理功能(称为“垃圾回收”)对它们进行分配和回收时都需要系统开销。 但是,也对垃圾回收进行了高度优化,在大多数情况下它不会引起性能问题

所有数组都是引用类型,即使其元素是值类型也不例外.数组是从 System.Array 类隐式派生的,但可以通过 C# 提供的简化语法来声明和使用它们,如下面的示例所示:

Codeint[] num={1,2,3,4,5};
int len=num.Length;

引用类型完全支持继承.创建类时,可以从没有定义为 sealed 的任何其他接口或类继承,而其他类则可以从您创建的类继承并重写虚方法

5,文本值类型

在 C# 中,文本值从编译器接收类型。您可以通过在数字末尾追加一个字母来指定应如何类型化该数字文本。 例如,若要指定应按浮点数来处理值 4.56,则在该数字后追加一个“f”或“F”:4.56f。 如果没有追加字母,则编译器将为该文本推断一个类型。

6,泛型类型

一个类型可以通过一个或多个类型参数声明,而这些类型参数作为客户端代码在创建该类型的实例时提供的实际类型(具体类型)的占位符。这种类型称为“泛型类型”。 例如,.NET Framework 类型 System.Collections.Generic.List<T> 有一个类型参数,按照约定该类型参数的名称为 T。 在创建该类型的实例时,会指定列表将包含的对象的类型。如

List<int> list=new List<int>();

7,隐式类型

使用关键字 var隐式类型化一个局部变量(非类成员),该变量在编译时仍然会接收一个类型,但该类型是由编译器提供的

8,匿名类型

某些情况下为相关值的简单集合创建命名类型是不方便的,因为这些相关值不准备在方法边界外存储或传递。可以创建匿名类型来实现此目的。

9,可以为null的类型

普通的值类型不能有 null 值。但是,可以通过在类型后面附加 ? 来创建可以为 null 值的类型。 例如,int? 是一个也可以具有 null值的 int 类型。 在 CTS 中,可以为 null 的类型是泛型结构类型 System.Nullable<T> 的实例。 在向其数值可能为 null 的数据库传入数据和从中传出数据时,可以为 null 的类型尤其有用。

以上内容参考msdn的C#编程指南,仅仅为了学习,如有不妥,请指出。谢谢

时间: 2024-10-06 01:14:31

C#的类型、变量和值的相关文章

JavaScript基础 == 等于 比较运算符 只比较两个变量的值,不管类型

镇场诗: 清心感悟智慧语,不着世间名与利.学水处下纳百川,舍尽贡高我慢意. 学有小成返哺根,愿铸一良心博客.诚心于此写经验,愿见文者得启发.------------------------------------------ code: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=ut

JavaScript基础 === 全等于 比较运算符 既比较两个变量的值,也比较两个变量的类型

镇场诗: 清心感悟智慧语,不着世间名与利.学水处下纳百川,舍尽贡高我慢意. 学有小成返哺根,愿铸一良心博客.诚心于此写经验,愿见文者得启发.------------------------------------------ code: 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=ut

【javascript】详解变量,值,类型和宿主对象

前言 我眼中的<javascript高级程序设计> 和<你不知道的javascript>是这样的:如果<javascript高级程序设计>是本教科书的话, <你不知道的javascript>就是那本王后雄有以下两点: 1. 老师会教你: 考试最后的准备仍然要“回归课本”2. 在1的前提下并不妨碍我们希望拥有一本好用的“王后雄” JS数据类型 JS类型分类 讲到类型, 首先要说的当然是JS的类型分类, 对于这一点,<javascript高级语言程序设计&

浅谈PHP变量的值类型和引用类型

看到网友在讨论PHP的&符号,要彻底理解它的用法,就有必要讨论一下变量的两种形式. PHP的变量在内存中是这样存储的,变量保存的并不直接是值的内容,而是地址.例如: $a = 1; 我们看起来,似乎变量$a直接存储了 1 这个值.而实际情况是,PHP解释器创建了变量$a,将值:1 存入内存中的某个地方,再将值的地址存到变量$a中. 需要取值时,先找到变量$a中的地址,再根据地址找到变量的值. 往下看: echo $a; 会输出1,PHP解释器会这样完成这一样代码:找到$a中存储的地址,根据地址找

PHP变量的值类型和引用类型

PHP 变量在内存中保存的并不直接是值的内容而是值的地址.比如: $a = 1; 从表面上看起来似乎是 $a 直接存储了 1 这个值.但是实际情况是,PHP 解释器创建了变量 $a , 将值 1 存入内存中的某个地方,再将值的地址存到变量中. 需要取值时,先找到变量中 $a 的地址,再根据地址找到变量的值. 比如: echo $a; 当我们执行上面这个语句时,会输出 1 ,但是 PHP 解释器会完成这样一段代码:找到 $a 中存储 的地址(即:先取 $a 的地址),根据地址找到存在内存中某个地方

不借助任何中间变量将两个整形变量的值交换

今天在做题的时候,突然出现一道题,就是不借助中间变量,将两个整形变量的值互换,开始有点懵,这怎么换?后来还是用两个变量不停做加减变换,差不多有十几分钟,才终于凑出来了一种方法,一时兴起,我又从网上找了一下相关的资料,说是竟然有四种方法,我就看了一下,顺便学习一下. 在我们初学阶段,一般是定义一个新的变量,借助它完成交换. 例如:int a,b;a=1; b=2;int t;t=a; a=b; b=t;这种算法易于理解,对初学者来说,一般都是用“空瓶子来回倒换”帮助理解的,而且是赋值语句的经典应用

c# 值类型与引用类型 值传递与引用传递

值类型与引用类型: 值类型 :1.值类型大小固定.存储在栈上.  2.不能继承,只能实现接口 3.派生自valuetype int double char float byte bool enum struct decimal 引用类型:1.在栈上存储了一个地址实际存储在堆中,大小不固定. 2.数组.类.接口.委托 string 数组 类 接口 委托 值传递与引用传递: 值类型按值传递.值类型按引用传递.引用类型按值传递.引用类型按引用传递. 值传递:默认传递都是值传递 ,把栈中内容拷贝一份引用

变量的值传递

基本类型.字符串String--传递的是实参的值 在初始化定义变量m时,在内存中分配存储空间. m作为传入调用的方法中的形参n时,在被调用的方法中形参n会再分配独立于m的存储空间,所以在方法中n改变了值,但当方法调用结束之后,变量m的值仍为原先值. 集合.数组.对象--传递的是集合的引用.即方法中的集合和传递的集合是一样的,指向同一个集合.所以,如果改变方法中的集合,方法外的集合也会同步改变 初始化定义变量时,该变量存储的是指向值的引用. 如:List list = new ArryList()

JavaScript筑基篇(一)-&gt;变量、值与对象

JavaScript变量.值与对象 说明 JavaScript中变量.值.对象的理解.本文为了简化理解,前半部分暂时刨除与执行上下文的相关概念.另外本文是个人的见解,如有疑问或不正支持,欢迎提出指正和讨论! 目录 前言 参考来源 变量与值 区分变量与值 JS值的两大类型 堆内存与栈内存的区别 值与对象 结合执行上下文理解 前言 参考来源 前人栽树,后台乘凉,本文参考了以下来源 汤姆大叔:变量对象 变量与值 区分变量与值 和所有其它程序语言一样,JavaScript也有变量和值得概念 var a