Archive

Archive for the ‘ASP.NET’ Category

The NOTE of learning ASP.NET [19] 关于GC(内存回收机制)、对象的销毁和using的使用

2010年06月1日 留下评论
    这两天看了用来回收无用对象并释放其占用的内存空间的GC(内存回收机制)的相关内容。。。一个教学视频整整看了5遍才理解他说的意思,都是英文太难为我了。看后知道了什么样的对象是在GC的回收范围内的,并且了解了GC只有在内存不够用时才进行内存的回收。接下来就应该瞧瞧对象销毁和GC之间运作的流程与关系了。
     当GC回收对象时会调用对象中的一个Finalize方法,虽然我们可能在我们的类中没有写这个方法,但是它确实存在。因为我们的所有类都是继承自System.Object类的,而Finalize方法是Object类的一个protected的方法。我们从来不会手动去调用那个方法,因为那个方法是当GC销毁对象时才会由GC自动调用的。而且大多数时候我们并不用去关心这个方法GC会适时的自动处理对象并释放内存等资源。那什么时候才需要关注这个Finalize方法呢?答案是:当我们调用了不是由.NET运行时环境管理的资源时,像打开了系统中的文件,数据流等,最典型的是我们的对象在运行时打开了一个数据库连接,这个数据库连接资源不会因为我们的对象被销毁而自动释放,所以我们需要在Finalize方法中设置相应的释放数据库连接的代码,这样即使我们在编码时没有手动关闭数据库连接,GC也会在回收对象时为我们释放数据库连接资源。可是System.Object的Finalize方法是被保护的不能够进行重载,如果我们需要自定义对象被销毁前要做的工作就需要使用.NET为我们提供的析构函数,析构函数与类名相同,在类名前加上~来标识。例如 Person类的析构函数就应该为 ~Person(){ //这里执行我们释放资源等处理的代码 }
    说到这可能会发现就这个例子来说如果我们在对象中打开了数据库连接而且没有关闭,即使我们提供了释放数据库资源连接的析构函数,那个数据库连接也不会马上关闭,因为GC只有当内存不足时才去回收那些无用对象并执行它的析构函数。那么对于这种使用过后需要立即释放的资源我们则需要使我们的类实现IDisposable接口,并实现接口中的Dispose方法。我们把释放数据库连接资源或其他不是由.NET管理的资源的代码放到Dispose方法中。似乎Dispose方法和析构函数做的工作是一样的,确实,但是他们两个还是有区别的,析构函数由GC调用,而Dispose由我们自己调用。这样我们就可以在使用完这个对象后立即执行其Dispose方法来释放其中的非.NET管理的资源(例如数据库连接)。
 
        下面是一个实现了IDisposable接口及Dispose方法的类:
using System;
using System.Collections.Generic;
using System.Text;
namespace ObjectsAndClasses
{
  class DisposeDemo : IDisposable
  {
    private System.IO.FileStream fs = null;
    //alreadyDisposed变量用来监视我们的对象是否已经执行过Dispose方法
    private bool alreadyDisposed = false;
    public void Dispose()
    {
      if (!this.alreadyDisposed)
      {
        if (fs != null)
          fs.Close();
        Console.WriteLine("In Dispose");
      }
      this.alreadyDisposed = true;
      // 下面这行代码告诉GC在销毁对象的时候不用
      // 执行这个对象的析构函数,因为我们已经在Dispose
      // 方法中做了析构函数需要做的工作。这样可以使GC
      // 在回收对象时提高一些效率
     GC.SuppressFinalize(this);
    }
  }
}
 
下面是调用上面所写的类的示例:
    private static void TestDispose()
    {
      // Declare the variable:
      DisposeDemo demo = null;
      try
      {
        // Assign the variable a value:
        demo = new DisposeDemo();
      }
      finally
      {
        if (demo != null)
        {
          demo.Dispose();
        }
      }
    }
 
上面的方法可能使用起来稍微麻烦,其实我们还可以使用using,代码如下:
    private static void TestUsing()
    {
      // 下面代码同样是创建了一个对象赋值给了demo这个引用变量,
      // 只不过它被包含在using后边的括号中,使用了using 后,demo
      // 这个对象的域就限制在了using后的大括号中。当大括号中的代码
      // 执行到了末尾后则会自动调用demo对象的Dispose方法来对资源
      // 进行释放。实际上这段代码的作用和上一段是一样的,只是使用起
      // 来更为简便。需要注意的是,只有实现了IDisposable接口的类才能
      // 使用using来操作。
      using (DisposeDemo demo = new DisposeDemo())
      {
        // Do something with demo in here…
      }
    }
分类:ASP.NET

The NOTE of learning ASP.NET [18] 关于.NET(GC)内存回收机制

2010年06月1日 留下评论
    在.NET中不管是哪种类型的变量都占据着内存中的一段空间。int,datetime,float等基本数据类型在对应的内存空间中存放的是实际的数据,而引用变量则不同,引用变量所占的内存空间中存放的不是实际的对象数据,而是一段指向存放实际对象所在内存的地址,这个在C或者C++中被叫做指针,指向存放实际对象的内存的地址。一般创建一个引用变量并为它赋值的的流程(以创建Person类的对象为例):
    Person personOne = new Person();
    这条语句实际上分为三个步骤,
   (1)使用new命令在内存中创建了一个新的对象
   (2)创建Person类型的引用变量personOne(引用变量在使用前必须为其赋值,否则会编译报错,引用变量被声明后若未赋值它的值为null即未引用到任何对象)
   (3)将新建的对象所在内存的信息赋值给应用变量personOne。
    可以看出如果我们做了如上操作后再使用 personOne = null; 将personOne赋予null值的话,虽然引用变量被设置为空,但是它原先引用的对象实际上仍然存在于内存中。而我们其实并不用担心如何释放那个已经不再使用的对象所占的内存。.NET中的内存回收机制即GC(Garbage Collector)负责回收引用变量及其引用的实际对象的内存空间。
    我们需要关心两个问题:具备什么条件的对象会被GC回收并释放内存空间?GC什么时候才会回收那些已经无用的对象?
   (1)当一个内存中的对象不再被任何引用变量所引用时,它符合了被GC回收的条件。比如Person personOne = new Person();当我们把personOne设置成null时,personOne不再指向任何对象,而同时我们也无法再次访问之前personOne所指向的对象,所以这个对象对我们来说已经是没有用处的了。
   (2)GC不会在对象符合被回收的条件时立即进行回收并释放内存,它会判断在内存不够用时再去回收内存中的对象,如果内存足够大的话,它可能永远不会去回收那些仍存在于内存中但是已经无用的对象。
    了解了以上问题,就可以在编程中更好的控制资源的使用并更好的理解一些方法的用途。
   
分类:ASP.NET

The NOTE of learning ASP.NET [17] 关于VS2008中使用注释生成智能提示

2010年05月26日 留下评论
    在使用VS2008编写程序时,代码的智能提示带给我们很多实惠啊~当我们调用一个方法时,比如这里是一个Program类的RandomNumber方法,这个方法是static型的,我们在编程界面输入 Program.  输入了点后会弹出一个列表显示我们在这里可以调用的方法,我们继续输入RandomNumber,让列表中的RandomNumber处于选中状态,这时我们就能看到右侧会有一个黄色的提示框,显示了我们当前方法的一些信息,如重载情况以及注释说明。如图:
    我们可以为我们自己写的类里的方法添加注释来实现这样的效果,在我们想添加注释的方法上方输入三个’/’字符,VS就会自动帮你生成注释模板,然后我们在其中输入自己的注释即可。比如我们在Main函数上方输入///,即VS为我们生成了如下的注释:
      /// <summary>
      ///
      /// </summary>
      /// <param name="args"></param>
我们在<summary></summary>之间和<param name="args"></param>之间输入的注释会被显示到智能提示中。
分类:ASP.NET

The NOTE of learning ASP.NET [16] 关于类和对象以及封装

2010年05月25日 留下评论
    在很多测试代码中都是在Main函数中写了很多过程来演示我们的功能,但是我们知道我们的程序需要使用类,使用面向对象的方法来进行更好的设计。类是我们开发程序的基础。类作为对象的蓝图,描述了对象的共有属性和功能(方法)。很多教学里边的一个比喻很形象,如果说对象是房子,那类就是设计这个房子的设计图,我们可以使用这一个设计图来建设出很多相同的房子,这就是类和对象的关系。类由属性和方法组成。
    Class(类)中可以包含static或者instance的属性和方法。
    1.被声明为static型的属性是被所有这个类的对象所共享的,即每个对象中的这个属性都指向同一个值。
    2.默认的即instance型的属性是独立于单个对象的,也就是每个对象里的同一个instance属性都可以拥有不同的值。
    3.调用被声明为static型的方法不需要使用new关键字来显式的创建一个对象,可以直接由类来调用,一般被声明为static型的方法可以看作是类对外提供的服务。比如Directory.CreateDirectory(); 这个方法用来在我们的计算机中创建文件夹,这个方法就是一个static方法。我们并没有一个已经存在的文件夹供我们操作,我们只是使用了Directory类为我们提供的创建文件夹的服务。另外我们需要注意,因为static方法可以直接由类调用,而且我们在调用static方法的时候并没有创建那些类中定义的instance型的属性,所以我们不能在static方法中使用非static型的属性。
    4.默认的instance型的方法必须由具体对象来调用,即必须使用new关键字新建对象后由具体对象来调用。
    由下面的代码可以更好理解。
   using System;
    using System.Collections.Generic;
    using System.Text;
    namespace ClassesAndObjects
    {
        class MyCustomer
        {
            // 客户姓名 instance类型的属性,默认设置"客户姓名"属性为DefaultCustomName的值
            private string _CustomerName = DefaultCustomName;
            private string _CustomerID; // 客户ID instance属性
            public static string DefaultCustomName = "Unknow"; // 默认的客户姓名 static类型的属性
          
            // 类MyCustomer的构造函数,当类被创建时自动调用。与类名同名,不需要定义返回值,可以添加
            // 参数,可以提供多个具有不同参数类型或不同参数个数的构造函数,这样当我们
            // 新建对象时会根据我们传入参数的类型和个数来决定使用哪个构造函数,即重载。
            public MyCustomer(string CustomerID)
            {
                 _CustomerID = CustomerID;
            }
           
            // 以下CustomerID和CustomerName可以看到并不是普通的方法,实际上是对我们类的属性_CustomName和
            // _CustomID的封装如果我们类的属性可以直接被外界访问并随意设置它的值对我们的程序来说是很
            // 危险的。比如使用者把客户的姓名设置成数字"123"很明显,名字是数字是说不通的,所以我们可以使用封装来
            // 限制使用者对我们类的属性的操作。封装里包含了get和set两个关键字,对_CustomerID的封装我们只提供了get,
            // 这样_CustomerID对外界来说实际上是一个只读属性,CustomerName提供了对_CustomName
            // 的最简单的封装,在实际使用中我们可以在set里判断value的值,当value符合一定规则后才赋值给我们
            // 的_CustomName属性。
            public string CustomerID
            {
                get { return _CustomerID; }
            }
            public string CustomerName
            {
                get { return _CustomerName; }
                set { _CustomerName = value; }
            }
 
            static void Main(string[] args)
            {
                 MyCustomer custA = new MyCustomer("AAAA"); //创建一个对象,使用了带一个字符串参数的构造函数
                 MyCustomer custB = new MyCustomer("BBBB");
 
                 Console.WriteLine("custA’s CustomerID is {0}",custA.CustomerID); // 输出:custA’s CustomerID is AAAA
                 Console.WriteLine("custB’s CustomerID is {0}",custB.CustomerID); // 输出:custB’s CustomerID is BBBB
 
                 // 输出:custA’s CustomerName is Unknow
                 Console.WriteLine("custA’s CustomerName is {0}",custA.CustomerName);
                  // 输出:custB’s CustomerName is Unknow
                 Console.WriteLine("custB’s CustomerName is {0}",custB.CustomerName); 
                 Console.WriteLine();
 
                 // 对custA对象的_CustomerName属性赋值
                 custA.CustomerName = "CUSTA’S NAME";
                  //在这里通过类名来调用更改static型属性DefaultCustomName 的值。 
                 MyCustomer.DefaultCustomName = "Arvin";
                 // 这次创建的对象的默认客户名字将会是上一行设置的 “Arvin”
                 MyCustomer custC = new MyCustomer("CCCC");
                
                 // 输出:custA’s CustomerName is CUSTA’S NAME
                 Console.WriteLine("custA’s CustomerName is {0}",custA.CustomerName);
                 // 输出:custB’s CustomerName is Unknow
                 Console.WriteLine("custB’s CustomerName is {0}",custB.CustomerName);
                  // 输出:custC’s CustomerName is Arvin
                 Console.WriteLine("custC’s CustomerName is {0}",custC.CustomerName);
            }
        }
    }
分类:ASP.NET

The NOTE of learning ASP.NET [15] 关于.NET字符串类的使用

2010年05月22日 留下评论
字符串是开发当中使用最多的数据类型,以下整理字符串类的相关属性和方法:
  • Empty属性  String.Empty代表了一个空的字符串,但是不等于null,null是对象未初始化的状态
    可以使用 emptyString == String.Empty 这样的表达式来判断emptyString变量是否为空字符串。
  • Length属性 返回调用此方法字符串的字符个数。例如:myName = "Arvin Rong",这时使用
    myName.Length将会返回int型数值10。
  • Chars属性 例如存在一个字符串myName = "Arvin Rong",这时可以使用myName[0]取得字符串
    的第一个字符’A’,或者把0替换为任意小于字符串长度的数字。返回的值为char型
  • //比较字符串的相关方法——————————————————————
  • Compare方法 使用两个字符串作为参数,如果第一个参数小于第二个参数则返回负数,如果相等
    返回0,如果大于第二个参数则返回正数。这里说的大小指的是字符的ASCII码的大小,Compare方法
    是逐字符比较的,先比较两字符串的第一个字符,如果不相等则返回结果(正数,0或者负数),如果
    相等则继续比较到长度较短的字符串的最后一个字符。
  • Equals方法 使用两个字符串作为参数,比较两个字符串是否相等。String.Equals(stringA,stringB)
  • CompareTo方法 由第一个字符串调用此方法,第二个字符串作为参数。 返回结果和Compare是一样的。
  • //检索字符串的相关方法——————————————————————–
  • StartsWith方法,EndsWith方法,Contains方法,均由第一个字符串调用,第二个字符串作为参数传入,
    如果在第一个字符串中检索到第二个字符串则返回true。
  • IndexOf方法 由第一个字符串调用,第二个字符串作为参数传入,如果在第一个字符串中检索到第二个字符串
    则返回第二个字符串在第一个字符串中的位置。例如:myName = "Arvin Rong"; myName.IndexOf("Rong")
    会返回数值6
  • //编辑字符串的相关方法——————————————————————–
  • Insert方法 由第一个字符串调用,添加另外一个字符串到第一个字符串的特定位置。
  • Remove方法 由字符串调用,从字符串中移除一段字符串。例如:myName = "Arvin Rong";
    myName.Remove(5)返回字符串"Arvin",或者myName.Remove(5,1)返回字符串"ArvinRong"
    5代表起始位置,1代表需要移除的字符个数,默认不设置的话会把起始位置到最后一个字符都移除。
  • Replace方法 由字符串调用,传入两个字符串作为参数,第一个字符串为要替换的目标字符串,第二个字符串
    为需要替换成的实际字符串。
  • Trim方法 由字符串调用,去除字符串两侧的空格。例如:myName.Trim();
  • TrimStart方法 由字符串调用,去除字符串前端的空格。
  • TrimEnd方法 由字符串调用,去除字符串末尾的空格。
  • PadLeft方法,PadRight方法 由字符串调用传入整型值作为参数,设置一个长度,若调用此方法的字符串不足
    设置的长度。则用空格或者特定的字符补足。例如 myFirstName = "Arvin"; myFirstName.PadLeft(7) 会
    返回字符串"  Arvin",在Arvin前加了两个空格来补足长度为7个字符。我们也可以调用myFirstName.PadLeft(7,’-‘)
    用第二个参数 ‘-‘ 来设定我们需要的特定用来补足长的的字符。这个调用的结果是返回字符串"–Arvin"
  • ToUpper,ToLower方法 由字符串调用返回字符串的大写形式或者小写形式。
  • Substring方法 用来在字符串中提取特定的一段字符串。可以有一个或两个参数,第一个为要开始截取的位置,
    第二个为截取的长度,若不提供第二个参数默认提取到字符串末尾。例如:myName = "Arvin Rong";myName.Substring(6)
    会返回"Rong",myName.Substring(6,2)则返回"Ro".

    Substring方法可以配合IndexOf方法使用,例如:myName = "Arvin-Rong";
    myName.Substring(myName.IndexOf(‘-‘)+1) 返回字符串"Rong"

  • Split方法 由字符串调用,传入包含分隔符的字符串或字符数组作为参数,返回由传入分隔符分隔后生成的字符串数组。
    例如:testString = "stringA,stringB/stringC"; char[] separatorList = {’,’, ‘/’}; testString.Split(separatorList);
    返回字符串数组里面包含了三个字符串分别是 "stringA","stingB","stringC"
  • 需要注意以上编辑字符串的方法都不会改变调用方法的字符串本身,而是创建了一个新的字符串然后返回。
    例如:
    myName = "Arvin Rong";tempString =  myName.Remove(5) 返回字符串"Arvin"赋值给tempString;
    但是myName本身的值仍为 "Arvin Rong";
分类:ASP.NET

The NOTE of learning ASP.NET [14] 使用.NET Framework中System.Xml命名空间下的类读写XML文件

2010年05月20日 留下评论

     .NET中对XML读写进行了很好的支持,在.NET Framework中Xml命名空间下提供了很多类来对XML文件进行读写等操作。在需要读写XML文件时时我们可以在代码顶部输入using System.Xml 来告诉编译器和运行时环境我们需要使用此命名空间下的类。
     首先回顾下关于XML的基本信息:
     1.XML 全称 Extensible Makeup Language 扩展标记语言,可以用来存储格式化的数据。
     2.XML 是基于(elements)元素的
     3.element由开始标记,元素内容以及结束标记组成。
     4.元素的属性可以存储当前标签的信息。

      以下是XML示例代码片段,这里我们存储了关于章节的信息,我们存储了两个章节,并存储了他们的标题:           
         <chapters total="2">
                <chapter>Data Types, Variables and Operators</chapter>
                <chapter>Language Fundamentals</chapter>
         </chapters>
        
 了解.Net Framework中XML读写相关的类:
     1.XmlWriter类 我们使用这个类把XML写入文件或者内存中,它的常用方法及属性如下:
        Create方法 创建一个新的实例,调用时传入XML文件的名称作为参数。
        WriteStartDocument方法 输出XML的定义头:类似 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
        WriteStartElement方法 输出元素开始部分,就是上边XML示例中的<chapters total="2">这行。
        WriteEndElement 方法  输出元素结束部分  </chapters>
        WriteElementString方法 一次性输出包括元素开始部分,元素内容和元素结束部分。可以一次性输出后面的内容,<chapter>Language Fundamentals</chapter>

    2.XmlWriterSettings类 我们使用这个类来设置我们写入XML的一些格式信息。
       Indent属性 可以设置为true或者false 来设置当我们写入XML的元素时,元素是否使用缩进。
       IndentChars属性 可以定义我们使用缩进时使用的分隔符。
       NewLineChars属性 定义我们写入元素时换行使用的字符。

    3.XmlReader类 我们使用这个类来读取文件或内存中的XML文件,它的常用方法及属性如下:
      Create方法 创建一个新的XML文件引用实例,调用时传入XML文件的名称作为参数。
      Read方法 一次读取一个元素的节点,返回true或者false
      NodeType属性 判断当前Read方法读取的标记节点类型,是element还是文本。
      ReadToFollowing方法 传递一个我们要查找的element名称作为参数,    和Read方法基本一样,只是我们这里是要找寻特定名称的element

示例代码如下:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml;
 
namespace UsingNetFramework
{
  class Program
  {
    static void Main(string[] args)
    {
            static void WriteAndReadXML()  // 这里只定义了一个静态方法,执行下面的代码块
           {

                   // 首先new一个XmlWriterSettings类的实例,起个名字叫settings,用来定义使用XmlWriter类来输出XML的格式设置。
                   XmlWriterSettings settings = new XmlWriterSettings();

                   // 设置settings对象的Indent属性为true,这样在使用XmlWriter输出XML时会自动使用缩进
                   // 如果这里设置成false则输出的XML文件会没有任何换行缩进等格式
                   settings.Indent = true; 
                  
                   // 设置换行字符
                   settings.NewLineChars = "rn";

                   // 通过调用XmlWriter类的静态方法Create来新建一个写XML文件的writer对象,如果文件已经存在会覆盖他里面的内容。
                   // 调用这个方法传进了两个参数,第一个是字符串型,为我们要创建的文件的名称,包括要存放的位置的全路径。
                   // 第二个参数是我们在上边创建的settings对象,这样可以让writer使用我们定义好的格式来输出XML。
                   XmlWriter writer = XmlWriter.Create("c:\test.xml", settings);
 
                   writer.WriteStartDocument(true); //输出XML的定义头:类似 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
                   writer.WriteStartElement("chapters"); //输出chapters元素的开始标签<chapters>
                   // 下面一行代码为上一行代码输出的chapters元素添加一个属性,这样我们实际看到的效果应该是<chapters total="2">
                   writer.WriteAttributeString("total", "2"); 

                   // 下面一行代码一次输出了一个完整的元素,一次性输出包括元素开始部分,元素内容和元素结束部分。
                   // 输出效果所示:<chapter>Data Types, Variables and Operators</chapter>
                   writer.WriteElementString( "chapter", "Data Types, Variables and Operators");
                   writer.WriteElementString( "chapter", "Language Fundamentals");
                  
                   // 输出chatpers元素的结束部分</chapters>
                   writer.WriteEndElement();

                   // 结束我们的输出,文件在我们使用Create方法时已经在硬盘中生成,但是只有当我们调用了Close方法后以上内容才会真正输出到文本文件中。
                   writer.Close();
                   
                   /// 上面的部门示例了写XML的一般方法,下面则是读取XML的一般方法
                   // 读取XML文件我们使用XmlReader类,首先也需要使用XmlReader的Create方法来新建一个XmlReader的对象,
                   // 这实际上是我们XML文件的一个引用,方法的参数为我们要读取文件的名称包括其全路径。
                   XmlReader reader = XmlReader.Create("c,:\test.xml");        ///"c:\test.xml"中的\是使用了转义字符
 
                  // Read the XML one node at a time
                  // 这里使用了一个while循环,如果reader对象的Read方法返回true,说明我们读取到了XML文件中的节点信息
                  // 返回false的时候说明我们已经读取完所有信息。可以这么理解,使用一次Read方法如果读到数据,即把当前读到的节点
                  // 数据保存到reader对象中,然后我们就可以调用reader对象的属性来读取当前读到的节点的信息。
                  while (reader.Read())
                  {
                        if (reader.NodeType == XmlNodeType.Text)
                       {
                            Console.WriteLine(reader.Value);
                       }
                   }

                   // 当我们读取完毕需要使用Close方法来关闭这个读取流。
                   reader.Close();
 
                   Console.WriteLine();

                   // 上面演示了XmlReader的Read方法,下面是XmlReader类的ReadToFollowing方法的示例
                   // 同样需要使用XmlReader的Create方法来新建一个XmlReader的对象,可能有人会问为什么上面已经新建了一个
                   // XmlReader的对象,而这里不能直接使用呢。这是因为无论是使用Read方法还是ReadToFollowing方法,读取
                   // XML的顺序都是从上到下而不能回到顶部重新读取的。所以每次需要重新读取XML文件都需要新建一个XmlReader类的对象。
                   reader = XmlReader.Create("c:\test.xml");
                   
                   // 区别于Read方法依次读取XML的每个节点信息,ReadToFollowing方法可以读取特定名称的节点的信息
                   // 这里选择只读取元素名称为chapter的元素节点。
                   while (reader.ReadToFollowing("chapter"))
                   {
                          // 读到一个元素节点后我们可以使用它的信息进行操作,这里输出了这个元素的内容
                          Console.WriteLine(reader.ReadInnerXml());
                   }
                    
                   // 关闭读取流
                   reader.Close();
               }
        }
     }
  }

分类:ASP.NET

The NOTE of learning ASP.NET [13] 关于.NET中的Constants,Enumerations,Structs

2010年05月20日 留下评论
Constants 即常量,可以像普通变量一样使用const来定义,但是它的值在应用程序运行中是不可以改变的,例如我们常见的圆周率。
Enumerations 是枚举型, 是一些相关的常量的集合,使用enum标识来定义。它有两个域,名字和数字域。使用时通过枚举量名.名字域来调用。
       例:enum weekDay
            {
        Sunday = 1,
        Monday = 2,
        Tuesday = 3,
        Wednesday = 4,
        Thursday = 5,
        Friday = 6,
        Saturday = 7,
            }
           我们调用的时候就可以使用weekDay.Sunday 这样来调用,返回值为1
 
Structs 及结构型, 和枚举型类似,但是相当于枚举类型的数字域可以存储任何类型数据。使用struct来定义
    例:struct Person
        {
            public string FirstName;
            public string LastName;
            public int Age;
              }
             Person person ;
        person.FirstName = "Lei";
        person.LastName = "Rong"
        person.Age = 25;
        System.Console.Write("{0} {1} is a {2} years old boy.",person.FirstName,person.LastName,person.Age);
 
 
分类:ASP.NET