专注于自动化测试,性能测试.......

发布新日志

  • 任务管理器中进程的各列的含义

    2012-12-03 18:44:21

      
    描述

    PID(进程标识符)

    唯一标识所运行进程的编号。

    用户名

    运行该进程的用户帐户。

    会话标识

    标识进程所有者的编号。当多个用户登录时,每个用户都有一个唯一的会话标识。

    CPU 的使用

    自上次更新以来,进程使用 CPU 的时间百分比(列标题中列为“CPU”)。

    CPU 时间

    进程自其启动以来使用的总处理时间(以秒为单位)。

    内存 - 工作集

    私人工作集中的内存数量与进程正在使用且可以由其他进程共享的内存数量的总和。

    内存 - 峰值工作集

    进程所使用的工作集内存的最大数量。

    内存 - 工作集增量

    进程所使用的工作集内存中的更改量。

    内存 - 私人工作集

    工作集的子集,它专门描述了某个进程正在使用且无法与其他进程共享的内存数量。

    内存 - 提交大小

    为某进程使用而保留的虚拟内存的数量。

    内存 - 页面缓冲池

    由内核或驱动程序代表进程分配的可分页内核内存的数量。可分页内存是可写入其他存储媒体(例如硬盘)的内存。

    内存 - 非页面缓冲池

    由内核或驱动程序代表进程分配的不可分页的内核内存的数量。不可分页的内存是不能写入其他存储媒体的内存。

    页面错误

    自某进程启动后该进程生成的页面错误数。进程访问当前不在工作集的内存页面时会出现页面错误。某些页面错误要求从磁盘中检索页面内容;其他的页面错误可在不访问磁盘的情况下解决。

    页面错误增量

    自上次更新以来页面错误数量的变化。

    基本优先级

    优先排名,它确定了所计划进程的线程顺序。

    句柄

    进程的对象表中的对象句柄数。

    线程数

    进程中运行的线程数。

    USER 对象

    当前由进程使用的 USER 对象数。USER 对象是来自 Window 管理器的对象,它包含窗口、菜单、光标、图标、挂接、加速器、监视器、键盘布局及其他内部对象。

    GDI 对象

    图形输出设备应用程序编程接口 (API) 的图形设备接口 (GDI) 库中的对象数量。

    I/O 读取

    由进程(包括文件、网络和设备 I/O)生成的读取输入/输出操作的数量。无法计算定向到 CONSOLE(控制台输入对象)句柄的 I/O 读取数量。

    I/O 写入

    由进程(包括文件、网络和设备 I/O)生成的写入输入/输出操作的数量。无法计算定向到 CONSOLE(控制台输入对象)句柄的 I/O 写入数量。

    I/O 其他

    由既非读取又非写入的进程(包括文件、网络和设备 I/O)生成的输入/输出操作的数量。此类操作的示例是控制功能。无法计算定向到 CONSOLE(控制台输入对象)句柄的 I/O 其他操作数量。

    I/O 读取字节数

    由进程(包括文件、网络和设备 I/O)生成的输入/输出操作所读取的字节数。无法计算定向到 CONSOLE(控制台输入对象)句柄的 I/O 读取字节数。

    I/O 写入字节数

    由进程(包括文件、网络和设备 I/O)生成的输入/输出操作所写入的字节数。无法计算定向到 CONSOLE(控制台输入对象)句柄的 I/O 写入字节数。

    I/O 其他字节数

    由既非读取又非写入的进程(包括文件、网络和设备 I/O)生成的输入/输出操作所传输的字节数。此类操作的示例是控制功能。无法计算定向到 CONSOLE(控制台输入对象)句柄的 I/O 其他字节数。

    映像路径名称

    硬盘上的进程位置。

    命令行

    指定为创建进程的完整命令行。

    用户帐户控制(UAC)虚拟化

    确定为此进程启用、禁用还是不允许使用用户帐户控制 (UAC) 虚拟化。UAC 虚拟化将文件和注册表写入错误重定向到每用户位置。

    描述

    进程的描述。

    数据执行保护

    是否为此进程启用或禁用数据执行保护。有关详细信息,请参阅 什么是数据执行保护?

  • 【原创】如何操纵已打开的IE窗口

    2011-12-28 11:20:09

       本文为原创文章,转载请注明出处(TIB工作室)

       在Vs中新建一个控制台程序,引用SHDocVw.dll和mshtml.dll.
       首先初始化ShellWindowsClass,以获取当前打开的所有IE窗口,然后再其中轮循所有的IE窗口,根据页面的标题找到想操纵的IE窗口,然后把IWebBrowser2对象的Document对象转换为IHTMLDocument2,然后就可以操纵其中的元素了,具体代码如下:

    using System;

    using System.Collections.Generic;

    using System.Text;

    using mshtml;

    using SHDocVw;

    namespace GetIEWindow

    {

    class Program

        {

     static void Main(string[] args)

            {

                string browerTitle = "百度一下,你就知道";

                string elementId = "kw";

                string inputValue = "my test";

                var allBrowsers = new ShellWindowsClass();

                IHTMLDocument2 currDocument =null;     

                foreach (IWebBrowser2 browser in allBrowsers)

                {

                    if (((IHTMLDocument2)browser.Document).title == browerTitle)

                    {

                        currDocument = (IHTMLDocument2)browser.Document;

                    }

                }

                IHTMLElementCollection elements = currDocument.all;

                foreach (IHTMLElement element in element)

                {

                    if (element.id == elementId)

                    {

                        element.setAttribute("value", inputValue, 0);

                    }

                }

                Console.ReadLine();

            }

        }

    }

  • 使用SMO比较表结构差异(原创)

    2009-09-28 23:00:36

       今天因为工作需要,需对比SQL Server2005数据库中相同表的字段是否相同。之前,在SQL server2000数据库中做过同样的事情,利用的是VBS脚本操作DMO来实现的。不过很可惜,在SQL server2005已经不在使用DMO,而是启用了新的SMO。而且VBS脚本也不再支持SMO。所以,只能用C#来进行了。具体思路:先比较两个数据库,找到相同的表,然后比较表的列,找出差异。

    使用SMO,需先引用Microsoft.SqlServer.ConnectionInfo,

    Microsoft.SqlServer.Smo 这两个命名空间。

    源代码:

    using System;
    using System.Collections.Generic;
    using System.Text;
    using Microsoft.SqlServer.Management.Smo;
    using Microsoft.SqlServer.Server;
    using Microsoft.SqlServer.Management.Common;
    using Microsoft.SqlServer;
    using System.Data.SqlClient;
    using System.Collections;


    namespace SMOsample
    {
        class Program
        {
            static void Main(string[] args)
            {
                string connectionString1 = "server =192.168.40.148;database = JcyPD;uid =sa;pwd=1";
                SqlConnection connection1 = new SqlConnection(connectionString1);
                Server server1 = new Server(new ServerConnection(connection1));
                Database db1 = server1.Databases["JcyPD"];

                string connectionString2 = "server =192.168.40.110;database = Jcy40 ;uid =sa;pwd=sa";
                SqlConnection connection2 = new SqlConnection(connectionString2);
                Server server2 = new Server(new ServerConnection(connection2));
                Database db2 = server2.Databases["Jcy40"];

                ArrayList al1 = new ArrayList();
                ArrayList al2 = new ArrayList();

                for (int x = 0; x < db1.Tables.Count; x++)
                {
                    al1.Add(db1.Tables[x].Name.ToString());
                }

     

                for (int y = 0; y < db2.Tables.Count; y++)
                {
                    al2.Add(db2.Tables[y].Name.ToString());
                }

                for (int m = 0; m < al1.Count; m++)
                {
                    for (int n = 0; n < al2.Count; n++)
                    {
                        if (al1[m].ToString() == al2[n].ToString())
                        {
                            ArrayList cal1 = new ArrayList();
                            ArrayList cal2 = new ArrayList();
                           
                            foreach(Column c1 in  db1.Tables[al1[m].ToString()].Columns)
                            {
                                cal1.Add(c1.Name.ToString());
                            }

                            foreach (Column c2 in db2.Tables[al2[n].ToString()].Columns)
                            {
                                cal2.Add(c2.Name.ToString());
                            }

                            foreach (string s in cal2)
                            {
                                if (!cal1.Contains(s))
                                {
                                    Console.WriteLine(al2[n].ToString() + " : " + s);

                                }
                            }

                        }
                    }
                }
                Console.WriteLine("完毕!");
                Console.ReadLine();

            }
        }
    }

  • 生成C#的win32api非托管代码工具

    2009-09-23 21:26:40

      这几天在研究如何用C#利用win32api编写GUI测试工具,由于经常要编写win32的非托管代码,比较麻烦。微软好像也没有相关工具。现找到一个生成win32的c#非托管代码的工具,与大家共享。界面如下:

    打开工具,File->open,打开win32api.txt文件,win32api的常量,结构以及类型就会加载。选中你需要的项,点击“Add”,就会生成相应代码了。

    注意: 我编译工具时,窗口初始化时会自动加载win32api.txt,而且文件路径是硬编码的,所以在打开工具之前,要把win32api.txt放到C:\下。当然,也可以用源代码重新修改编译。

    工具:

    CSharpAPITextViewer.rar(8.59 KB)

    win32api.txt :

    WIN32API.rar(531 KB)

    源代码:

    CSharpAPITextViewer(源代码).rar(218 KB)

  • 使用DotNetSkin 更换winform的皮肤

    2009-09-19 21:33:34

       在日常工作中经常会使用C#开发一些测试辅助小工具,不过工具一承不变的外观确实会使人审美疲劳,所以就尝试更换一下form的皮肤,经google后,发现一个非常简单易用的控件-DotNetSkin。

    官方给出的效果图:

    首先下载链接:

    http://files.cnblogs.com/mgod/dotnetskin2005.rar  里面有演示代码
    然后下载http://files.cnblogs.com/mgod/v1.20.1.rar 将对应DLL版本覆盖到Bin目录中

    安装:

    1.右键点击vs的工具栏的常规Tab,选择“添加项”

    2.添加DotNetSkin.dll后,确定。DotNetSkin控件就出现在了工具栏中。

    使用方法:

    1 把SkinUI控件拖放到Form窗口上

    2 设置skinUI.FileName属性,选择*.skin文件

    3 设置skinUI.active 为true

    4 编译并运行你的程序就可以了

  • 列出Windows服务,并填充到word中

    2008-08-18 16:55:20

      直接把代码复制到文本中,后缀改为.vbs,双击即可运行,也可以复制到测试工具中运行

    ' Add a Formatted Table to a Word Document


    Set ōbjWord = CreateObject("Word.Application")
    objWord.Visible = True
    Set ōbjDoc = objWord.Documents.Add()

    Set ōbjRange = objDoc.Range()
    objDoc.Tables.Add objRange,1,3
    Set ōbjTable = objDoc.Tables(1)

    x=1

    strComputer = "."
    Set ōbjWMIService = _
      GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colItems = objWMIService.ExecQuery("Select * from Win32_Service ")
    For Each objItem in colItems
      If x > 1 Then
      objTable.Rows.Add()
      End If
      objTable.Cell(x, 1).Range.Font.Bold = True
      objTable.Cell(x, 1).Range.Text = objItem.Name
      objTable.Cell(x, 2).Range.text = objItem.DisplayName
      objTable.Cell(x, 3).Range.text = objItem.State
      x = x + 1
    Next

  • C#连接和查询Sql server数据库

    2008-06-06 15:27:27

     

    using System;
    using System.Data;
    using System.Data.SqlClient;
    using System.Collections.Generic;
    using System.Text;

    namespace 数据库学习
    {
        class Program
        {
            static void Main(string[] args)
            {

    //使用轻量级的SqlDataReader显示数据
                //指定Sql Server提供者的连接字符串
                string connString = "server=192.168.99.45;database =northwind;uid =sa;pwd=1";

                //建立连接对象

                SqlConnection Sqlconn = new SqlConnection(connString);
                //打开连接
                Sqlconn.Open();

                ////为上面的连接指定Command对象
                //SqlCommand thiscommand = Sqlconn.CreateCommand();
                //thiscommand.CommandText = "select customerID,companyName from customers";

                ////为指定的command对象执行DataReader
                //SqlDataReader thisSqlDataReader = thiscommand.ExecuteReader();

                ////只要有数据
                //while (thisSqlDataReader.Read())
                //{
                ////输出数据
                //    Console.WriteLine("\t{0}\t{1}", thisSqlDataReader["customerId"], thisSqlDataReader["companyName"]);
                //}
                ////关闭读取
                //thisSqlDataReader.Close();
                ////关闭连接
                //Sqlconn.Close();
                //Console.ReadLine();

    //使用dataset显示数据

                // 查询字符串
                string   thisCommand = "select customerID,companyName from customers";

                //创建SqlDataAdapter对象,有两个参数,一个是查询字符串,一个是连接对象
                SqlDataAdapter SqlDap = new SqlDataAdapter(thisCommand,Sqlconn);
              
                //创建DataSet对象

                DataSet thisDataset = new DataSet();
               
                //使用SqlDataAdapter的Fill方法填充DataSet,有两个参数,一个是创建的DataSet实例,一个是填入的表

                SqlDap.Fill(thisDataset, "customers");

                //显示查询结果

                foreach (DataRow theRow in thisDataset.Tables["customers"].Rows)

                {
                    Console.WriteLine(theRow["customerID"] + "\t" + theRow["companyName"]);
                }
                Sqlconn.Close();

                Console.ReadLine();

            }
        }
    }

  • 推荐-一款代码编辑器 nodepad++

    2008-05-21 17:53:43

      试用感觉还是不错的,主要是现在学习C#,为了更好的锻炼自己对代码编写的能力,不想在IDE中编写代码,但是在记事本中又太麻烦而且不易读,所以找到了这个工具,还不错,

    下载连接地址:http://www.crsky.com/soft/7737.html

    下面是摘录的介绍:

    Notepad++ 是在 Windows 环境之下的一个免费的代码编辑器。

    为了产生小巧且有效率的代码编辑器,这个在GPL许可证下的自由软体开发专案采用 win32 api 和 STL 以 C++ 程式语言撰写成,并且选用功能强大的编辑模组 Scintilla。多亏它的轻巧与执行效率,Notepad++ 可完美地取代微软视窗的记事本。

    这个软体开发专案已趋于成熟阶段,然而目前只有一个人从事软体开发与维护的工作,瑕疵在所难免。

    Notepad++ 的主要功能:

    语法高亮度显示及语法折叠功能
    支持的程式语言: C, C++ , Java , C#, XML, HTML, PHP, Javascrīpt , RC resource file, makefile, ASCII art file (extension .nfo) , doxygen, ini file, batch file, ASP , VB/VBS source files , SQL , Objective-C , CSS, Pascal, Perl, Python, Lua, TCL, Assembler, Ruby, Lisp, Scheme, Properties, Diff, Smalltalk, Postscrīpt 及 VHDL.

    打印所见即所得(WYSIWYG) ,如果你有彩色打印机,你可以把你的原始码以多种颜色打印出来。

    用户自定程式语言
    字词自动完成功能(Auto-completion)
    支持同时编辑多重文件
    支持多重视窗同步编辑
    支持Regular Expression搜寻及取代
    完全支持拖曳功能
    内部视窗位置可任意移动
    自动侦测开启档案状态
    放大与缩小功能
    书签
    高亮度括号及缩排辅助
    用户可储存数百个巨集指令,并分配予键盘捷径

  • blog要搬家了,感觉51的blog使用起来不是很方便,特别是文章没有折页。

    2008-03-13 23:39:57

    blog要搬家了,感觉51的blog使用起来不是很方便,特别是文章没有折页。
  • C#的字符串常用的操作方法

    2008-03-13 17:36:22

    字符串的用法:
    1)截取字符串
    使用substring方法,而该方法在c#中有两个重载函数:substring(参数),substring(参数1,参数2),用法如下:
    string A ="I'm a string";
    sting B=A.substring(1);
    sting C=A.substring(1,6);
    其中传入的参数1为字符串的起始位置,字符子串B将截取字符串A的第2个字符之后所有的字符.
    字符子串C将截取字符串A的第2个字符之后的长度为6的字符串.
    参数必须大于等于0,如果小于0将抛出ArgumentOutOfRange异常.
    2)字符串转化为字符数组
    首先,string类型变量可以看成为char变量的只读数组,这样就可以使用如下语法访问每个字符:
    string A = "i'm a string"
    char B =A[1];
    而要是把字符串变为可写的char数组,可以使用TocharArray()方法:
    char [] = A.Tochararray();
    使用B.Length获取字符串的长度.
    3)转换大小写
    <string>.ToLower() 转换成小写
    <string>.ToUpper() 转换成大写
    4)删除字符串种的空格或者指定的字符
     删除字符串前后的空格:
    <string>.Trim()
    删除指定的字符:
    首先利用char数组指定特定字符
    char[] C ={' ','e',}
    <string>.Trim(C)
    也可以使用Trimstart(),TrimEnd()分别去除前后的空格或者指定的字符
    5)在字符串前后添加空格或者指定的字符
    <string>.PadLeft(参数) <string>.PadRight(参数)  参数为添加空格后字符串的长度
    <string>.PadLeft(参数1,参数2) 参数1为使字符串达到的长度,参数2为指定添加的字符.
    6)indexof()的用法
    IndexOf()
    查找字串中指定字符或字串首次出现的位置,返回首索引值,如:
    str1.IndexOf("字"); //查找“字”在str1中的索引值(位置)
    str1.IndexOf("字串");//查找“字串”的第一个字符在str1中的索引值(位置)
    str1.IndexOf("字",start,end);//从str1第start+1个字符起,查找end个字符,查找“字”在字符串STR1中的位置[从第一个字符算起]注意:start+end不能大于str1的长度
    7)insert()的用法
    <string>.insert(参数1,参数2)
    参数1为插入子字符串的其实位置,参数2为要插入的子字符串
    8)比较字符串的大小
    Compare(str1,str2)——比较两个字符串 str1,str2的大小,如果大于返回正数,等于返回0,小于返回负数
    9)替换指定的字符串
    String.Replace(参数1,参数2)——用指定的字符替换字符串中的指定字符
    字符串的处理方法还有很多,这里就不一一列举了,以后用到在慢慢学习.

    using System;

    namespace testStringApp
    {
     /// <summary>
     /// Class1 的摘要说明。
     /// </summary>
     class Class1
     {
      /// <summary>
      /// 应用程序的主入口点。
      /// </summary>
      [STAThread]
      static void Main(string[] args)
      {
       //
       // TODO: 在此处添加代码以启动应用程序
       //
       //直接给字符串赋值
       string strA = "This is a string";
       Console.WriteLine ("strA: "+strA);
       //ToCharArray方法,建立Char数组;IndexOf方法,查找子串位置
       char[] charArray = strA.ToCharArray(0,strA.IndexOf ("string"));
       //使用new关键字初始化字符串,作用等同于charArray.ToString()
       string strB = new string (charArray);
       Console.WriteLine ("strB: "+strB);
       //Insert方法,插入子串
       string strC = strA.Insert (strA.IndexOf ("string"),"another ");
       Console.WriteLine ("strC: "+strC);
       //+操作符,连接字符串
       string strD = strA + strB;
       Console.WriteLine ("strD: "+strD);
       //String.Concat方法,链接字符串,相当于+
       //String.Equals方法,比较字符串,相当于==
       if (String.Equals (strD,String.Concat (strA,strB)))
       {
        if (strD == strA+strB)
        {
         Console.WriteLine ("String.Concat等同于+\n,System.Equals等同于==");
        }
       }
       //Trim方法,删除字符串中的空格或其它字符
       string strE = strA.Trim();
       Console.WriteLine ("strE: "+strE);
       //使用\显示引号"和反斜线\
       string strF = "C:\\Windows\\System32\\";
       Console.WriteLine ("\"" + strF + "\"");
       //使用@显示引号"和反斜线\
       string strG = @"C:\Windows\System32\";
       Console.WriteLine (@"""" + strG + @"""");
       //string转换为int型
       string strH = "12345";
       int theInt = int.Parse (strH);
       Console.WriteLine ("科学计数显示整数{0:E}",theInt);
       Console.WriteLine ("十六进制显示整数{0:X}",theInt);
       //string转换为float型
       string strI = "123.45";
       float theFloat = float.Parse (strI);
       Console.WriteLine ("显示浮点数,指定小数位数{0:F4}",theFloat);
                Console.ReadLine();
      }
     }
    }

  • C#的事件机制

    2008-03-12 14:29:57

    /*
     * 我已经在该例中把创建,发送,触发,处理事件的过程用一步步的步骤描述出来了,不过现在还是迷迷糊糊的,有不明白的地方请见谅.
     */


    using System;
    //命名空间
    namespace testEventApp
    {
    /*第一步:创建一个委托*/

        //定义委托Class2_Event_Handler
        public delegate void Class2_Event_Handler(object sender, string strEventArg);

     /// <summary>
     /// Class1 的摘要说明。
     /// </summary>
    /*=======================================================================
        事件接收方类
    =======================================================================*/

     
        //定义类Class1
     class Class1
     {
            //创建类Class1的默认构造器
      public Class1()
      {
       Console.WriteLine ("Class1>>>创建一个Class1对象!");
      }
    /*第四步:编写事件处理函数,该函数要具有与第一步中创建的委托相同的签名
     */
            private void On_Class2Event(object sender, string strEventArg)
            { //Class2中事件发生时的处理函数
                Console.WriteLine("Class1>>>收到Class2中的事件:" + strEventArg);
                if (strEventArg == "exit")
                {
                    Class2 senderRef = (Class2)sender;
                    //取消事件处理函数与Class2中事件的关联
                    senderRef.Class2_Event -= new Class2_Event_Handler(this.On_Class2Event);
                    Console.WriteLine("Class1>>>不再接收Class2的事件!输入exit退出!");
                }
            }
      /// <summary>
      /// 应用程序的主入口点。
      /// </summary>
      [STAThread]

      static void Main(string[] args)
      {
       //
       // TODO: 在此处添加代码以启动应用程序
       //
       Class1 aClass1 = new Class1 ();
       Class2 aClass2 = new Class2 (); //创建一个Class2对象
    /*第五步:将第四步中编写的事件处理函数与事件建立关联(也就是利用事件处理函数生成第一步中创建的委托的委托实例)
     */
       //将事件处理函数与Class2中的事件关联
       aClass2.Class2_Event += new Class2_Event_Handler(aClass1.On_Class2Event );
       //调用Class2中的方法,等待其触发事件
       aClass2.Class2_Event_Riser ();
      }

      
     }
        /*=====================================================================
            事件发送方类
        =====================================================================*/
        //定义类Class2
     class Class2
     {
            /*定义类Class2的构造器*/
      public Class2()
      {
       Console.WriteLine ("Class2>>>创建一个Class2对象!");
      }

    /*第二步:利用第一步中创建的委托创建事件,这样委托和时间之间就建立了关联(.NET类库中的很多事件都是已经订制好的,所以它们都有相应的
      委托,在编写关联时间处理程序(也就是有事件发生时我们要执行的方法的时候)我们需要和这个委托相同的签名。*/
      //利用delegate,定义一个事件
            //在类中声明一个事件的格式: public event 委托名 事件名
      public event Class2_Event_Handler Class2_Event;

    /*第三步:创建可以触发事件的方法*/

      //一个可以触发事件的方法
      public void Class2_Event_Riser()
      {
       string strRead;
       while(true)
       {
        Console.Write ("Class2>>>");
        strRead = Console.ReadLine ();

        if ( Class2_Event!=null )//当事件处理函数存在时
        {
         Console.WriteLine ("Class2>>>发送事件:"+strRead);
         Class2_Event(this, strRead);//触发delegate中的事件处理函数
        }
        else if (strRead == "exit")
        {
         System.Environment .Exit (-1);    
        }
       }
      }
     }
    }

  • C#的装箱和拆箱

    2008-03-07 10:21:36

    C#的装箱和拆箱

    using System;

    namespace testBoxingApp
    {
     /// <summary>
     /// Class1 的摘要说明。
     /// </summary>
     class Class1
     {
      /// <summary>
      /// 应用程序的主入口点。
      /// </summary>
      [STAThread]
      static void Main(string[] args)
      {
       //
       // TODO: 在此处添加代码以启动应用程序
       //
                /*
                 * 在理解装箱和拆箱的概念之前,现了解一下有关的基本概念:
                 * 1)在.net中的通用类型系统(common type system)中,所有的类型都是对象,都是派生自system.object。
                 * 2)CTS支持两组类型:值类型和引用类型。值类型的变量包含实际数据,会在内存中分配空间;引用类型的变量类型指针,而没有在
                 * 内存中分配空间。
                 * 3)装箱:将值类型转换成引用类型的过程(隐式转换)
                 * 4)拆箱:将引用类型转换成值类型的过程(显示转换)
                 由于在C#2.0中引入了泛型的概念,取代了装箱和拆箱,所以这里就不再赘述了。
                 */
       short i = 1;
       object ōbjectOne = i; //装箱,隐式类型转换
       Console.WriteLine ("{0} Boxing to object:{1}",ObjectOne.GetType(),ObjectOne);
       short j;    
       j = (short)ObjectOne; //拆箱,显示类型转换
       Console.WriteLine ("object Unboxing to short :{0}",j);
       
       try      //错误的拆箱
       {
        int k;
        k = (int)ObjectOne;
        Console.WriteLine ("object Unboxing to int: {0}",k);
       }
       catch(InvalidCastException ex){
        Console.WriteLine ( ex.Message );
       }

       object ōbjectTwo = new Class2 ();
       try      //错误的拆箱
       {
        short m;
        m = (short)ObjectTwo;
        Console.WriteLine ("object Unboxing to short :{0}",m);
       }
       catch(InvalidCastException ex)
       {
        Console.WriteLine ( ex.Message );
       }

       Class2 aRef;   //Class2的一个引用变量
       aRef = (Class2) ObjectTwo;
       Console.WriteLine (aRef.s );
      }
     }

     class Class2
     {
      public short s;
      public Class2()
      {
       Console.WriteLine ("A Class2 Object!");
       s = 10;
      }
     }
    }

  • C#的抽象类和方法,重载,覆盖,隐藏

    2008-03-06 16:38:07

    第四例 C#的抽象类和方法,重载,覆盖,隐藏

     

    using System;

    namespace testClassApp
    {
       /// <summary>
       /// Class1 的摘要说明。
       /// </summary>
       class Class1
       {
           /// <summary>
           /// 应用程序的主入口点。
           /// </summary>
           [STAThread]
           static void Main(string[] args)
           {
              //
              // TODO: 在此处添加代码以启动应用程序
              //

              double len = 2.5;
              double wid = 3.0;
              double rad = 4.1;
              Rectangle aRect = new Rectangle();
              aRect.length = len;
              aRect.width = wid;
              Circle aCirc = new Circle (rad);
              Console.WriteLine ("Area of Rect is:{0}",aRect.Area ());
              Console.WriteLine ("Area of Circ is:{0}",aCirc.Area ());
           }
       }

       abstract class Shape             //抽象基类,不可实例化
       
    /* 1)声明一个抽象类使用abstract关键字
         * 2)只要包含抽象方法的类就是抽象类(哪怕只有一个),当一个抽象类中所有的方法都是抽象时,我们就可以定义成接口
         * 一个类可以包含一个或多个抽象方法
         * 3)抽象类中可以存在非抽象的方法(方法可以有具体的实现)
         * 4)抽象类不能被实例化
         * 5)实现抽象类用":",实现抽象方法用override关键字
         * 6)抽象类可以被抽象类所继承,结果仍是抽象类
         * 7)抽象方法被实现后,不能更改修饰符
        */
        {
           public const double pi=3.14;  //常量
           protected double x, y;        //私有,可继承变量
           
    //构造函数
            /*
             1)对象最初对对象进行实例化的过程叫做构造阶段,这个过程就是由构造函数完成的,构造函数就是用于初始化数据的函数。
             2)所有的对象(类)都有一个默认的构造函数,没有参数,与类同名,但一个类可以包含几个带参数的构造函数
            称为非默认的构造函数。
             3)构造函数用new关键字来调用,例如:
             * 调用默认构造函数:类名类的实例名= new 类名();
             * 调用非默认构造函数:类名类的实例名= new 类名(参数);
             * 4)构造函数与字段,属性,方法一样,可以使公共或者私有的
             * 5)构造函数只是在对象被建立时调用,就是一句代码也不写或没有实现构造函数,那么这个类也会建立,
             * 这个函数只是说在对象在建立的时候给了一个给这个对象初始设置值的机会
             */
            public Shape()               //默认构造函数
           {
              x=y=0;
           }
           public Shape(double x,double y)  //带参数构造函数
           {
              this.x = x;
              this.y = y;
           }
           public abstract double Area();   //抽象方法,需重载
            /*
             * 1)声明一个抽象方法使用abstract关键字,抽象方法只包含方法定义,但没有具体实现的方法,需要其子类或者子类的子类来具体实现
             * 2)子类继承抽象父类后,可以使用override关键字覆盖父类中的抽象方法,并做具体的实现。也可以不实现抽象方法,留给后代实现,
             * 这时子类仍旧是一个抽象类,必须声明为abstract
             * 3)继承的抽象方法不可以被隐藏
             */

        }

       class Rectangle: Shape
       {
           public Rectangle():base(){}
           public Rectangle(double x, double y): base(x,y){}//使用基类构造函数
           
    /*
             1) 隐式调用基类构造函数:如果没有明确指明base()( 即不使用base() ),子类会自动调用基类的默认构造器
             2) 显示调用:上面的就是显示调用,使用base(参数)
             */
            public override double Area()   //函数覆盖,子类继承抽象父类后,可以使用override关键字覆盖父类中的抽象方法,并做具体的实现。
                //也可以不实现抽象方法,留给后代实现,
           {
              return (x*y);
           }
           public double length   //属性:矩形长度
           {
              get
              {
                 return x;
              }
              set
              {
                 if (value>0){x = value;}
              }
           }
           public double width    //属性:矩形宽度
           {
              get
              {
                 return y;
              }
              set
              {
                 if (value>0){y = value;}
              }
           }

       }

       class Ellipse: Shape
       {
           public Ellipse(double x, double y):base(x,y){}//使用基类Shape的构造函数
           public override double Area() //函数覆盖
           {
              return pi*x*y;
           }
       }
       class Circle: Ellipse
       {
           public Circle(double r):base(r,0){}  //使用基类Ellipse的构造函数
           public override double Area() //函数覆盖
           {
              return pi*x*x;
           }
       }
           
       //隐藏:在子类中创建与父类中的方法具有相同签名(相同的方法名,相同的参数列表-参数类型和次序)的方法(可以带有"virtual"或"override"关键字)即可实现,但建议使用"new"关键字,以明确地隐藏。
              //只能使用"override"关键字来覆盖(override)父类中标记为"virtual"、"abstract"或"override"的方法,而子类中标记为override的方法,也必须是父类中标记为"virtual"、"abstract"或"override"的方法。
              //覆盖(override):必须使用override关键字,可以被覆盖的方法包括标记为abstract,virtual,和override的方法;
              //隐藏:使用new关键字,也可不使用关键字,可以被隐藏的方法包括一般方法,和标记为virtual"或"override"的方法;
              //重载(overload):不需要任何特殊的关键字
              //静态方法可以被隐藏或重载
        /*重载,覆盖,隐藏之间的区别
         重载(overload)用于同一类中的成员函数,其特征为:
         * 1)在同一类中
         * 2)相同的函数名
         * 3)参数不同(包括参数类型不同,或参数个数不同,或两者都不同,注意:和返回值没关系)
         * 4)和是否虚函数无关
         覆盖(override)是指派生类函数覆盖基类函数,其特征为:
         * 1)不同的范围(分别位于派生类与基类)
         * 2)相同的函数名称
         * 3)参数相同
         * 4)基类函数必须是虚函数
         隐藏(hide)是指派生类的函数屏蔽了与其同名的基类函数,其特征为:
         * 1)不同的范围(分别位于派生类与基类)
         * 2)相同的函数名
         (3)若参数不同,基类函数无virtual关键字,基类函数将会被隐藏。(因为派生类和基类不在同一范围,所以是隐藏而不是重载);
        ()若参数不同,基类函数有virtual关键字。基类函数将会被隐藏。(因为派生类和基类不在同一范围,所以是隐藏而不是重载;因为参数不同,所以是隐藏而不是覆盖);
        ()若参数相同,基类函数无virtual关键字。基类函数将会被隐藏。(因为基类函数不是虚函数,所以是隐藏而不是覆盖)。
        ()若参数相同,基类函数有virtual关键字。如果基类函数有多个重载版本,且派生类并没有重写所有的同名虚函数,当在派生类中调用函数时,基类中未被重写的虚函数将被隐藏。(当然,被重写的函数就是覆盖了)。
    注意: 如果想在派生类中调用基类中的被隐藏的函数,可以在派生类中填写如下代码:using Base::Fun2
         */


    }

  • C#的类型转换,枚举,结构

    2008-03-05 15:31:50

    下面的代码是取自<<c#100例>>,讲的是c#中的类型转换,复杂的数据类型(结构和枚举,数组没有讲),我在代码中加入了一些关于这些知识的注释(参考<<c#入门经典>>)

    using System;

    namespace CValueApp
    {
     /// <summary>
     /// Class1 的摘要说明。
     /// </summary>
     class Class1
     {
      /// <summary>
      /// 应用程序的主入口点。
      /// </summary>
      [STAThread]
      static void Main(string[] args)
      {
       //
       // TODO: 在此处添加代码以启动应用程序
       //
       
       //值类型定义及初始化
       System.Int16 aShort = new System.Int16 ();//System.Int16 等同与 short关键字
       byte aByte = new Byte ();
       decimal aDecimal = 100.5m;
       char aChar = 'y';
       Console.WriteLine ("值类型的初始化值:{0} ,{1} ,{2} ,{3}",aShort,aByte,aDecimal,aChar);

       //值类型的赋值与操作
       float aFloat = 123.123F;
       bool aBool = ((aFloat > 121) && (aFloat < 125));
       if (aBool) {
        int aInteger;
        aInteger = (int) aFloat;//显示转换
                    /*
                     显示转换的格式:
                     类型B 变量B;
                     类型A 变量A;
                     变量B = (类型B)变量A
                     显示转换的相关问题:
                     1) 在试图把一个值转换为一个不合适的值时,会造成数据丢失,这时可以使用关键字checked和unchecked(表达式的溢出检查环境),
                     如下:变量B = checked((类型B)变量A),同时也可以在编译器中修改配置,使编译器在编译时检查转换是否溢出。方法见p77
                     2) 使用Convert命令进行类型转换,有可能转换不成功,这是编译器会出现错误提示。
                     3) 对于混合的转换,就根据运算符的优先级,在处理每个运算符时执行转换。
                     */

                    double aDouble;
        aDouble = aFloat;  //隐式转换
                    /*
                     隐式转换的一般规则:
                     1)bool和string类型没有隐式转换
                     2)任何类型A,只要其取值范围完全包含在类型B的取值范围内,就可以隐式转换成类型B
                     */

        Console.WriteLine ("类型转换结果:{0} ,{1}",aInteger,aDouble);
       }
       
       //枚举类型的使用
                //1)把枚举值转换成其他类型,必须进行显示转换
                //2)以该程序为例,要使long类型转换成Data类型(枚举类型)也需要显示转换,而且这样转换会在应用程序的后面违反逻辑。
                //3)枚举类型转换成string,必须使用Convert.ToString或者ToString
                //4)string转换成枚举类型:(枚举类型) 枚举 = (枚举类型)Enum.Parse(typeof(枚举类型),string);
       long x = (long)Data.Min ;
       long y = (long)Data.Max ;
       Console.WriteLine ("枚举类型的值:{0} ,{1}",x,y);

       //结构的使用
       MyPoint aPoint;
       aPoint.x = 10;
       aPoint.y = 100;
       Console.WriteLine ("结构类型的值:{0} ,{1}",aPoint.x ,aPoint.y );
                Console.ReadLine();

      }

      //枚举类型的定义
            /*
              1)枚举的基本类型可以是 byte,sbyte,short,ushort,int,uint,long,ulong,默认的情况下,每个值都会根据定义的顺序(从0开始),自动赋给对应的基本类型值。
              可以重写这个赋值过程,使用=运算符,给每个枚举赋值。
                 */
      enum Data : long {   
       Min = 255L, Mid = 1024L, Max = 32768L
      };

      //结构的定义
            //1) 结构和类在使用上没有区别,唯一的区别是在内存里的存储方式,结构是值类型,而类是引用类型,
            //在需要访问快,计算少的地方用结构,计算多的地方用类。

      public struct MyPoint
      {
       public int x, y;
       public MyPoint( int x, int y)
       {
        this.x = x;
        this.y = y;
       }
      }
     }
    }

  • 开始学习C#了

    2008-02-26 16:51:32

       为了更好的职业发展,学习编程看样是势在必行了,先在空间里立个里程碑,争取以后每天可以把学到的知识整理到空间里来(有些困难,尽量吧).

Open Toolbar