FlySky

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  30 随笔 :: 16 文章 :: 65 评论 :: 0 引用

2008年11月13日 #

组件映射(User-Name)

关联属性是个复杂类型的持久化类,但不是实体既:数据库中没有表与该属性对应,但该类的属性要持久保存

<component name="name" class="Name">
<property name="firstName" column="first_name"/>
<property name="middleName" column="middle_name"/>
<property name="lastName" column="last_name"/>
</component>

当组件映射的属性不能和表中的字段简单对应的时候可以选择实现:

org.hibenrate.usertype.UserTypeorg.hibernate.usertype.CompositeUserType

1、首先创建domain类:

package com.zhaosoft.domain;

import java.util.Date;

public class User {
 private int id;
 private Name name;
 private Date birthday;
 private int ver;   //版本号,悲观锁
 public int getVer() {
  return ver;
 }
 public void setVer(int ver) {
  this.ver = ver;
 }
 public int getId() {
  return id;
 }
 public void setId(int id) {
  this.id = id;
 }

 public Date getBirthday() {
  return birthday;
 }
 public void setBirthday(Date birthday) {
  this.birthday = birthday;
 }
 public Name getName() {
  return name;
 }
 public void setName(Name name) {
  this.name = name;
 }

}

2、实现组件映射对应的类:

package com.zhaosoft.domain;

public class Name {
 private String firstName;
 private String middleName;
 private String lastName;

 public String getMiddleName() {
  return middleName;
 }

 public void setMiddleName(String middleName) {
  this.middleName = middleName;
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

}

3、映射关系:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.zhaosoft.domain">
     <!-- 当discriminator-value值为0时,为普通员工 -->
 <class name="User">  
 <cache usage="read-only"/>
  <id name="id">
      <!-- 表示主键为自动增长 -->
   <generator class="hilo"/>
  </id>
  <!--版本号-->
  <version name="ver"/>
  <property name="birthday" type="date"/>
  
 <!-- 组件映射 -->
 <component name="name" class="Name">
 <property name="firstName" column="first_name"/>
 <property name="middleName" column="middle_name"/>
 <property name="lastName" column="last_name"/>
 </component>
 </class>
 <query name="getUserByID">
   <![CDATA[from User ]]>
 </query>
 
</hibernate-mapping>

posted @ 2008-11-13 13:31 赵晓雷 阅读(15) | 评论 (0)编辑

我在前面写了关于继承映射的整个继承树对应一张表的例子,但是他存在以一定的弊端。在数据表中会产生大量的null值。

为了避免这种情况的发生。我们可以这样去做:

<joined-subclass name="Skiller" table="skiller">
   <key column="emp_id"/>
   <property name="skill"></property>
 </joined-subclass>
 
 <joined-subclass name="Sales" table="sales">
   <key column="emp_id"/>
   <property name="sell"></property>
 </joined-subclass>

通过使用joined-subclass映射,对每一个子类生成一张表。

1、domain类:

package com.zhaosoft.domain;

public class Employee {

 private int id;
 private String name;
 private Department depart;

 public int getId() {
  return id;

 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Department getDepart() {
  return depart;
 }

 public void setDepart(Department depart) {
  this.depart = depart;
 }

}
2、各个子类:

package com.zhaosoft.domain;

public class Sales extends Employee{

 private int sell;//销售额

 public int getSell() {
  return sell;
 }

 public void setSell(int sell) {
  this.sell = sell;
 }
}

---------------------------------------------

package com.zhaosoft.domain;

public class Skiller extends Employee{
 private String skill;

 public String getSkill() {
  return skill;
 }

 public void setSkill(String skill) {
  this.skill = skill;
 }
}

 

3、映射文件:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.zhaosoft.domain">
     <!-- 当discriminator-value值为0时,为普通员工 -->
 <class name="Employee" discriminator-value="0">  
  <id name="id">
      <!-- 表示主键为自动增长 -->
   <generator class="native"/>
  </id>
 <property name="name" type="string"/>
 <many-to-one name="depart" class="Department" column="depart_id"></many-to-one>
 
 <joined-subclass name="Skiller" table="skiller">
   <key column="emp_id"/>
   <property name="skill"></property>
 </joined-subclass>
 
 <joined-subclass name="Sales" table="sales">
   <key column="emp_id"/>
   <property name="sell"></property>
 </joined-subclass>
 
 </class>
 
</hibernate-mapping>

 

4、测试文件:

public static void add() {
  Session s = null;
  Transaction t=null;
  try {
   s=HibernateUtil.getSession();
   t = s.beginTransaction();
   t.begin();
   Department d = new Department();
   d.setName("销售部");

   Employee employee1 = new Employee();
   employee1.setName("小三");
   employee1.setDepart(d);

   Skiller employee2 = new Skiller();
   employee2.setName("李斯");
   employee2.setSkill("skill");
   employee2.setDepart(d);
   
   Sales employee3 = new Sales();
   employee3.setName("王五");
   employee3.setSell(100);
   employee3.setDepart(d);

   Set<Employee> set=new HashSet<Employee>();
   set.add(employee1);
   set.add(employee2);
   set.add(employee3);
   d.setEmps(set);
   s.save(d);
   s.save(employee1);
   s.save(employee2);
   s.save(employee3);
   
   t.commit();
  } catch (Exception e) {

  } finally {
   if (s != null) {
    s.close();
   }
  }
 }

posted @ 2008-11-13 13:29 赵晓雷 阅读(13) | 评论 (0)编辑

2008年10月24日 #

1、什么是ArrayList
? ? ArrayList就是传说中的动态数组,用MSDN中的说法,就是Array的复杂版本,它提供了如下一些好处:
动态的增加和减少元素
实现了ICollection和IList接口
灵活的设置数组的大小

2、如何使用ArrayList
? ? 最简单的例子:
ArrayList List = new ArrayList();
for( int i=0;i<10;i++ ) //给数组增加10个Int元素
List.Add(i);
//..程序做一些处理
List.RemoveAt(5);//将第6个元素移除
for( int i=0;i<3;i++ ) //再增加3个元素
?? List.Add(i+20);
Int32[] values = (Int32[])List.ToArray(typeof(Int32));//返回ArrayList包含的数组

这是一个简单的例子,虽然没有包含ArrayList所有的方法,但是可以反映出ArrayList最常用的用法

3、ArrayList重要的方法和属性
1)构造器
? ? ArrayList提供了三个构造器:
public ArrayList();
默认的构造器,将会以默认(16)的大小来初始化内部的数组
public ArrayList(ICollection);
用一个ICollection对象来构造,并将该集合的元素添加到ArrayList
public ArrayList(int);
用指定的大小来初始化内部的数组

2)IsSynchronized属性和ArrayList.Synchronized方法
? ? IsSynchronized属性指示当前的ArrayList实例是否支持线程同步,而ArrayList.Synchronized静态方法则会返回一个ArrayList的线程同步的封装。
? ? 如果使用非线程同步的实例,那么在多线程访问的时候,需要自己手动调用lock来保持线程同步,例如:
ArrayList list = new ArrayList();
//...
lock( list.SyncRoot ) //当ArrayList为非线程包装的时候,SyncRoot属性其实就是它自己,但是为了满足ICollection的SyncRoot定义,这里还是使用SyncRoot来保持源代码的规范性
{
list.Add( “Add a Item” );
}

? ???如果使用ArrayList.Synchronized方法返回的实例,那么就不用考虑线程同步的问题,这个实例本身就是线程安全的,实际上 ArrayList内部实现了一个保证线程同步的内部类,ArrayList.Synchronized返回的就是这个类的实例,它里面的每个属性都是用 了lock关键字来保证线程同步。

3)Count属性和Capacity属性
? ? Count属性是目前ArrayList包含的元素的数量,这个属性是只读的。
Capacity属性是目前ArrayList能够包含的最大数量,可以手动的设置这个属性,但是当设置为小于Count值的时候会引发一个异常。

4)Add、AddRange、Remove、RemoveAt、RemoveRange、Insert、InsertRange
? ? 这几个方法比较类似
Add方法用于添加一个元素到当前列表的末尾
AddRange方法用于添加一批元素到当前列表的末尾
Remove方法用于删除一个元素,通过元素本身的引用来删除
RemoveAt方法用于删除一个元素,通过索引值来删除
RemoveRange用于删除一批元素,通过指定开始的索引和删除的数量来删除
Insert用于添加一个元素到指定位置,列表后面的元素依次往后移动
InsertRange用于从指定位置开始添加一批元素,列表后面的元素依次往后移动

? ? 另外,还有几个类似的方法:
Clear方法用于清除现有所有的元素
Contains方法用来查找某个对象在不在列表之中

? ? 其他的我就不一一累赘了,大家可以查看MSDN,上面讲的更仔细
5)TrimSize方法
? ? 这个方法用于将ArrayList固定到实际元素的大小,当动态数组元素确定不在添加的时候,可以调用这个方法来释放空余的内存。
6)ToArray方法
? ? 这个方法把ArrayList的元素Copy到一个新的数组中。
4、ArrayList与数组转换
? ? 例1:
ArrayList List = new ArrayList();
List.Add(1);
List.Add(2);
List.Add(3);

Int32[] values = (Int32[])List.ToArray(typeof(Int32));

? ? 例2:
ArrayList List = new ArrayList();
List.Add(1);
List.Add(2);
List.Add(3);

Int32[] values = new Int32[List.Count];
List.CopyTo(values);

? ? 上面介绍了两种从ArrayList转换到数组的方法

? ? 例3:
ArrayList List = new ArrayList();
List.Add( “string” );
List.Add( 1 );
//往数组中添加不同类型的元素

object[] values = List.ToArray(typeof(object)); //正确
string[] values = (string[])List.ToArray(typeof(string)); //错误

和数组不一样,因为可以转换为Object数组,所以往ArrayList里面添加不同类型的元素是不会出错的,但是当调用ArrayList方法的时候,要么传递所有元素都可以正确转型的类型或者Object类型,否则将会抛出无法转型的异常。


5、ArrayList最佳使用建议
? ? 这一节我们来讨论ArrayList与数组的差别,以及ArrayList的效率问题
?? 1)ArrayList是Array的复杂版本
ArrayList内部封装了一个Object类型的数组,从一般的意义来说,它和数组没有本质的差别,甚至于ArrayList的许多方法,如Index、IndexOf、Contains、Sort等都是在内部数组的基础上直接调用Array的对应方法。
?? 2)内部的Object类型的影响
? ?? ?? ? 对于一般的引用类型来说,这部分的影响不是很大,但是对于值类型来说,往ArrayList里面添加和修改元素,都会引起装箱和拆箱的操作,频繁的操作可能会影响一部分效率。
但是恰恰对于大多数人,多数的应用都是使用值类型的数组。
消除这个影响是没有办法的,除非你不用它,否则就要承担一部分的效率损失,不过这部分的损失不会很大。
?? 3)数组扩容
这是对ArrayList效率影响比较大的一个因素。
每 当执行Add、AddRange、Insert、InsertRange等添加元素的方法,都会检查内部数组的容量是否不够了,如果是,它就会以当前容量 的两倍来重新构建一个数组,将旧元素Copy到新数组中,然后丢弃旧数组,在这个临界点的扩容操作,应该来说是比较影响效率的。
? ??? 例1:比如,一个可能有200个元素的数据动态添加到一个以默认16个元素大小创建的ArrayList中,将会经过:
16*2*2*2*2 = 256
四次的扩容才会满足最终的要求,那么如果一开始就以:
ArrayList List = new ArrayList( 210 );
的方式创建ArrayList,不仅会减少4次数组创建和Copy的操作,还会减少内存使用。

? ??? 例2:预计有30个元素而创建了一个ArrayList:
ArrayList List = new ArrayList(30);
在执行过程中,加入了31个元素,那么数组会扩充到60个元素的大小,而这时候不会有新的元素再增加进来,而且有没有调用TrimSize方法,那么就有1次扩容的操作,并且浪费了29个元素大小的空间。如果这时候,用:
ArrayList List = new ArrayList(40);
那么一切都解决了。
所以说,正确的预估可能的元素,并且在适当的时候调用TrimSize方法是提高ArrayList使用效率的重要途径。
? ? 4)频繁的调用IndexOf、Contains等方法(Sort、BinarySearch等方法经过优化,不在此列)引起的效率损失
首 先,我们要明确一点,ArrayList是动态数组,它不包括通过Key或者Value快速访问的算法,所以实际上调用IndexOf、Contains 等方法是执行的简单的循环来查找元素,所以频繁的调用此类方法并不比你自己写循环并且稍作优化来的快,如果有这方面的要求,建议使用Hashtable或 SortedList等键值对的集合。
ArrayList al=new ArrayList();

al.Add("How");
al.Add("are");
al.Add("you!");

al.Add(100);
al.Add(200);
al.Add(300);

al.Add(1.2);
al.Add(22.8);

.........

//第一种遍历 ArrayList 对象的方法
foreach(object o in al)
{
Console.Write(o.ToString()+" ");
}

//第二种遍历 ArrayList 对象的方法
IEnumerator ie=al.GetEnumerator();
while(ie.MoveNext())
{
Console.Write(ie.Curret.ToString()+" ");
}

//第三种遍历 ArrayList 对象的方法
我忘记了,好象是 利用 ArrayList对象的一个属性,它返回一此对象中的元素个数.

然后在利用索引
for(int i=0;i<Count;i++)
{
Console.Write(al[i].ToString()+" ");
}

posted @ 2008-10-24 20:34 赵晓雷 阅读(33) | 评论 (0)编辑

struts2动态方法调用
  struts2中无需配置就可以直接调用Action中非execute方法的方式,就是试用struts2的动态动态方法调用。
动态方法调用(Dynamic method Invoc)是在action的名字中使用感叹号(!)来标示要调用的方法名,其语法格式为
  actionName!methodname.action
 例如我们的配置如下:
<action name="login" class="com.pj.action.LoginAction" >
<result type="json"></result>
</action>  
当请求/login!query.action时,将调用LoginAction的query()方法,当请求/login!save.action时,将调用LoginAction的save()方法。
strust2提供了一种配置,用于禁用DMI,你可以在struts.xml文件中,使用constant元素将struts.enable.DynamicMethodInvocation属性设置为false,来关闭DMI。
posted @ 2008-10-24 20:30 赵晓雷 阅读(44) | 评论 (0)编辑

2008年10月11日 #

MemoryStream位于System.IO命名空间,为系统内存提供流式的读写操作。常作为其他流数据交换时的中间对象操作。

1、MemoryStream类封装一个字节数组,在构造实例时可以使用一个字节数组作为参数,但是数组的长度无法调整。使用默认无参数构造函数创建实例,可以使用Write方法写入,随着字节数据的写入,数组的大小自动调整。

2、在对MemoryStream类中数据流进行读取时,可以使用seek方法定位读取器的当前的位置,可以通过指定长度的数组一次性读取指定长度的数据。ReadByte方法每次读取一个字节,并将字节返回一个整数值。

3、UnicodeEncoding类中定义了Unicode中UTF-16编码的相关功能。通过其中的方法将字符串转换为字节,也可以将字节转换为字符串。

4、开始实例:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace MemoryStreamExample
{
    class Program
    {
        static void Main(string[] args)
        {
            int count;
            //从程序外部获取byte数组
            byte[] byteArray = getByteData();
            char[] charArray;
            UnicodeEncoding uniEncoding = new UnicodeEncoding();
            //创建MemoryStream内存流类的实例
            MemoryStream memStream = new MemoryStream(byteArray);
            count = 0;
            //显示内存流类实例的属性
            Console.WriteLine(
            "容量:{0}\t数量:{1}\t当前位置:{2}",
            memStream.Capacity.ToString(),
            memStream.Length.ToString(),
            memStream.Position.ToString());
            memStream.Seek(0, SeekOrigin.Begin);//将当前位置指定为流开始处
            byteArray = new byte[memStream.Length];
            count = memStream.Read(byteArray, 0, 20);//从流中读取前20个字节
            while (count < memStream.Length)//逐个读取剩下的字节
            {
                byteArray[count++] = Convert.ToByte(memStream.ReadByte());
            }
            //将字节数组转换为字符数组并显示出来
            charArray = new char[uniEncoding.GetCharCount(byteArray, 0, count)];
            uniEncoding.GetChars(byteArray, 0, count, charArray, 0);
            Console.WriteLine(charArray);
            Console.ReadLine();
        }
        private static byte[] getByteData()//获取外部字节数组的方法
        {
            UnicodeEncoding uniEncoding = new UnicodeEncoding();
            byte[] result = uniEncoding.GetBytes("memStream示例测试字符串");
            return result;
        }
    }
}

posted @ 2008-10-11 18:01 赵晓雷 阅读(817) | 评论 (0)编辑

在C#中实现文件的压缩和解压缩,需要使用第三方的组建完成。常用的是:SharpZipLib组建。

下载地址:http://www.icsharpcode.net/OpenSource/SharpZipLib/Download.aspx

1、压缩和解压缩有两种典型的算法,一种是BZIP2算法,另一种是GZIP算法。BZIP2能够获得较高的压缩比,但是压缩和解压缩比较耗时,GZIP效率比较高,但是压缩比较低。

2、BZIP2压缩算法的相关类,位于命名空间:ICSharpCode.SharpZipLib.BZip2中,算法要求指定输入流和输出流,并指定压缩方法使用的块大小,一般为2048.

3、GZIP压缩算法的相关类,位于命名空间:ICSharpCode.SharpZipLib.GZip中,首先创建GZipOutputStream类实例,作为压缩文件的输出流,使用GZipOutputStream类实例的Write方法,将从源文件读取的数据写入输入流。同时完成压缩运算。

4、使用实例:

 

class ZipAndUnzipFile
    {
        public static void GetZipAndUnzipFile(){

            string srcFile = @"..\..\testzip.txt";//准备压缩的文件路径
            string zipFile = @"..\..\testzip";//压缩后的文件路径
            string unzipFile = @"..\..\testzip_unzip.txt";//解压后的文件路径
            Console.WriteLine("使用BZIP开始压缩文件……");
            if (BZipFile(srcFile, zipFile + ".bz"))//使用BZIP压缩文件
            {
                Console.WriteLine("文件压缩完成");
            }
            else
            {
                Console.WriteLine("文件压缩失败");
            }
            Console.WriteLine("使用BZIP开始解压文件……");
            if (UnBzipFile(zipFile + ".bz", unzipFile))//使用BZIP解压文件
            {
                Console.WriteLine("文件解压完成");
            }
            else
            {
                Console.WriteLine("文件解压失败");
            }
            Console.WriteLine("使用GZIP开始压缩文件……");
            if (GZipFile(srcFile, zipFile + ".gz"))//使用GZIP压缩文件
            {
                Console.WriteLine("文件压缩完成");
            }
            else
            {
                Console.WriteLine("文件压缩失败");
            }
            Console.WriteLine("使用GZIP开始解压文件……");
            if (UnGzipFile(zipFile + ".gz", unzipFile))//使用GZIP解压文件
            {
                Console.WriteLine("文件解压完成");
            }
            else
            {
                Console.WriteLine("文件解压失败");
            }
            Console.ReadLine();
        }
    //使用BZIP压缩文件的方法
        static bool BZipFile(string sourcefilename, string zipfilename)
        {
            bool blResult;//表示压缩是否成功的返回结果
            //为源文件创建文件流实例,作为压缩方法的输入流参数
            FileStream srcFile = File.OpenRead(sourcefilename);
            //为压缩文件创建文件流实例,作为压缩方法的输出流参数
            FileStream zipFile = File.Open(zipfilename, FileMode.Create);
            try
            {
                //以4096字节作为一个块的方式压缩文件
                BZip2.Compress(srcFile, zipFile, 4096);
                blResult=true;
            }
            catch (Exception ee)
            {
                Console.WriteLine(ee.Message);
                blResult=false;
            }
            srcFile.Close();//关闭源文件流
            zipFile.Close();//关闭压缩文件流
            return blResult;
        }
        //使用BZIP解压文件的方法
        static bool UnBzipFile(string zipfilename,string unzipfilename)
        {
            bool blResult;//表示解压是否成功的返回结果
            //为压缩文件创建文件流实例,作为解压方法的输入流参数
            FileStream zipFile = File.OpenRead(zipfilename);
            //为目标文件创建文件流实例,作为解压方法的输出流参数
            FileStream destFile = File.Open(unzipfilename, FileMode.Create);
            try
            {
                BZip2.Decompress(zipFile, destFile);//解压文件
                blResult=true;
            }
            catch (Exception ee)
            {
                Console.WriteLine(ee.Message);
                blResult=false;
            }
            destFile.Close();//关闭目标文件流
            zipFile.Close();//关闭压缩文件流
            return blResult;
        }
        //使用GZIP压缩文件的方法
        static bool GZipFile(string sourcefilename, string zipfilename)
        {
            bool blResult;//表示压缩是否成功的返回结果
            //为源文件创建读取文件的流实例
            FileStream srcFile = File.OpenRead(sourcefilename);
            //为压缩文件创建写入文件的流实例,
            GZipOutputStream zipFile = new GZipOutputStream(File.Open(zipfilename,FileMode.Create));
            try
            {
                byte[] FileData = new byte[srcFile.Length];//创建缓冲数据
                srcFile.Read(FileData, 0, (int)srcFile.Length);//读取源文件
                zipFile.Write(FileData, 0, FileData.Length);//写入压缩文件
                blResult = true;
            }
            catch (Exception ee)
            {
                Console.WriteLine(ee.Message);
                blResult = false;
            }
            srcFile.Close();//关闭源文件
            zipFile.Close();//关闭压缩文件
            return blResult;
        }
        //使用GZIP解压文件的方法
        static bool UnGzipFile(string zipfilename, string unzipfilename)
        {
            bool blResult;//表示解压是否成功的返回结果
            //创建压缩文件的输入流实例
            GZipInputStream zipFile = new GZipInputStream(File.OpenRead(zipfilename));
            //创建目标文件的流
            FileStream destFile = File.Open(unzipfilename, FileMode.Create);
            try
            {
                int buffersize = 2048;//缓冲区的尺寸,一般是2048的倍数
                byte[] FileData = new byte[buffersize];//创建缓冲数据
                while(buffersize>0)//一直读取到文件末尾
                {
                    buffersize = zipFile.Read(FileData,0,buffersize);//读取压缩文件数据
                    destFile.Write(FileData,0,buffersize);//写入目标文件
                }
                blResult = true;
            }
            catch(Exception ee)
            {
                Console.WriteLine(ee.Message);
                blResult = false;
            }
            destFile.Close();//关闭目标文件
            zipFile.Close();//关闭压缩文件
            return blResult;
        }
    }

posted @ 2008-10-11 16:14 赵晓雷 阅读(209) | 评论 (1)编辑


    sizeof运算符的作用是获取指定数据类型的字节数。在C#中只能用于值类型,不能用于引用类型中,
    对于结构(struct),sizeof运算符可用于不安全的代码中。
    1、在VS2008编程环境中,unsafe代码的编译必须使用/unsafe参数参能编译。在项目属性中,将“生成”页签
   下的"允许不安全代码"选中,然后编译运行。
  
    class SizeofExample
    {
       public static void GetSizeofExample()
        {
            unsafe//表示不安全代码
            {
                //获取结构占用的字节长度,这句代码必须放在unsafe声明的范围内
                Console.WriteLine("MyPoint结构占用的字节数为:" + sizeof(MyPoint));
            }
            //以下显示各种基本数据类型的sizeof运算结果
            Console.WriteLine("sbyte数据类型的字节数为:" + sizeof(sbyte));
            Console.WriteLine("byte数据类型的字节数为:" + sizeof(byte));
            Console.WriteLine("short数据类型的字节数为:" + sizeof(short));
            Console.WriteLine("ushort数据类型的字节数为:" + sizeof(ushort));
            Console.WriteLine("int数据类型的字节数为:" + sizeof(int));
            Console.WriteLine("uint数据类型的字节数为:" + sizeof(uint));
            Console.WriteLine("long数据类型的字节数为:" + sizeof(long));
            Console.WriteLine("ulong数据类型的字节数为:" + sizeof(ulong));
            Console.WriteLine("char数据类型的字节数为:" + sizeof(char));
            Console.WriteLine("float数据类型的字节数为:" + sizeof(float));
            Console.WriteLine("double数据类型的字节数为:" + sizeof(double));
            Console.WriteLine("bool数据类型的字节数为:" + sizeof(bool));
            Console.ReadLine();
        }
        struct MyPoint//表示点的结构
        {
            public int X;//点的X座标
            public int Y;//点的Y座标
        }
    }
posted @ 2008-10-11 14:39 赵晓雷 阅读(799) | 评论 (2)编辑

2008年10月10日 #

      is运算符的作用是检查一个对象是否是指定的数据类型。
    1、  is运算符主要的作用是判断对象是否是兼容类型。在判断过程中,先将判断对象转换为指定的数据类型,如果转换失败,则返回false,不会抛出异常。

    2、 当子类b从父类a派生,形如b类实例is a的表达式返回true,而a类实例isb的表达式将返回false。
    class IsExample
    {
        public static void GetIsExample()
        {
            Person testpsn = new Person();//创建一个“人”类的实例
            Employee testemp = new Employee();//创建一个员工类的实例
            Department testdept = new Department();//创建一个部门类的实例
            Console.WriteLine("testpsn类实例是:");
            GetObjectType(testpsn);
            Console.WriteLine("-----------------");
            Console.WriteLine("testemp类实例是:");
            GetObjectType(testemp);
            Console.WriteLine("-----------------");
            Console.WriteLine("testemp类实例的empdept属性是:");
            GetObjectType(testemp.empdept);
            Console.WriteLine("-----------------");
            Console.WriteLine("testdept类实例是:");
            GetObjectType(testdept);
            Console.WriteLine("-----------------");
            Console.ReadLine();
        }
        static void GetObjectType(Object o)
        {
            if (o is Person)//判断对象是否“人”类
            {
                Console.WriteLine("--“人”类");
            }
            if (o is Employee)//判断对象是否员工类
            {
                Console.WriteLine("--员工类");
            }
            if (o is Department)//判断对象是否部门类
            {
                Console.WriteLine("--部门类");
            }
        }
    }

按f5运行,运行结果如下:

posted @ 2008-10-10 15:37 赵晓雷 阅读(108) | 评论 (1)编辑

2008年10月9日 #

    使用as运算符
     1.as运算符用于引用类型的转换和值类型的装箱。转换失败时,将转换为null,而不会引发异常。
     2.as运算符不能呢个用于自定义的类型转换,当需要进行用户自定义类型的转换时,应使用cast来转换。
    
    class AsExample
    {
       public static void GetAsExample()
        {
            ArrayList myarray = new ArrayList();//创建一个动态数组
            string asstring;//用来保存转换结果的字符串
            myarray.Add("The first string.");//向数组中添加不同数据类型的元素
            myarray.Add(23);
            myarray.Add("The second string.");
            myarray.Add(26);
            myarray.Add(41);
            myarray.Add("The third string.");
            foreach (Object obj in myarray)//使用foreach遍历数组
            {
                //将Object类型转换为string类型,as操作符只能在两个引用类型之间进行
                asstring = obj as string;
                if (asstring != null)//转换失败的结果是null,而不是空字符串
                    Console.WriteLine(obj as string);
            }
            Console.ReadLine();
        }
    }
posted @ 2008-10-09 20:57 赵晓雷 阅读(161) | 评论 (0)编辑

2008年6月7日 #

【1、最基本的弹出窗口代码】
  
  <SCRIPT LANGUAGE="javascript">
  <!--
  window.open ('page.html')
  -->
  </SCRIPT>
  
  因为着是一段javascripts代码,所以它们应该放在<SCRIPT LANGUAGE="javascript">标签和</script>之间。<!-- 和 -->是对一些版本低的浏览器起作用,在这些老浏览器中不会将标签中的代码作为文本显示出来。要养成这个好习惯啊。window.open ('page.html') 用于控制弹出新的窗口page.html,如果page.html不与主窗口在同一路径下,前面应写明路径,绝对路径(http://)和相对路径(../)均可。用单引号和双引号都可以,只是不要混用。这一段代码可以加入HTML的任意位置,<head>和</head>之间可以,<body>间</body>也可以,越前越早执行,尤其是页面代码长,又想使页面早点弹出就尽量往前放。
 
  【2、经过设置后的弹出窗口】
  
  下面再说一说弹出窗口的设置。只要再往上面的代码中加一点东西就可以了。 我们来定制这个弹出的窗口的外观,尺寸大小,弹出的位置以适应该页面的具体情况。
  
  <SCRIPT LANGUAGE="javascript">
  <!--
  window.open ('page.html', 'newwindow', 'height=100, width=400, top=0, left=0, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=n o, status=no') //这句要写成一行
  -->
  </SCRIPT>

  
  参数解释:
  
  <SCRIPT LANGUAGE="javascript"> js脚本开始;
  window.open 弹出新窗口的命令;
  'page.html' 弹出窗口的文件名;
  'newwindow' 弹出窗口的名字(不是文件名),非必须,可用空''代替;
  height=100 窗口高度;
  width=400 窗口宽度;
  top=0 窗口距离屏幕上方的象素值;
  left=0 窗口距离屏幕左侧的象素值;
  toolbar=no 是否显示工具栏,yes为显示;
  menubar,scrollbars 表示菜单栏和滚动栏。
  resizable=no 是否允许改变窗口大小,yes为允许;
  location=no 是否显示地址栏,yes为允许;
  status=no 是否显示状态栏内的信息(通常是文件已经打开),yes为允许;
  </SCRIPT> js脚本结束

  
  【3、用函数控制弹出窗口】

  
  下面是一个完整的代码。
  <html>
  <head>
  <script LANGUAGE="JavaScript">
  <!--
  function openwin() {
  window.open ("page.html", "newwindow", "height=100, width=400, toolbar =no, menubar=no, scrollbars=no, resizable=no, location=no, status=no") //写成一行
  }
  //-->
  </script>
  </head>
  <body onload="openwin()">
  任意的页面内容...
  </body>
  </html>

  这里定义了一个函数openwin(),函数内容就是打开一个窗口。在调用它之前没有任何用途。怎么调用呢?

  方法一:<body onload="openwin()"> 浏览器读页面时弹出窗口;
  方法二:<body onunload="openwin()"> 浏览器离开页面时弹出窗口;
  方法三:用一个连接调用:
  <a href="#" onclick="openwin()">打开一个窗口</a>
  注意:使用的“#”是虚连接。
  方法四:用一个按钮调用:
  <input type="button" onclick="openwin()" value="打开窗口">

 
 
  【4、同时弹出2个窗口】
  
   对源代码稍微改动一下:
  
  <script LANGUAGE="JavaScript">
  <!--
  function openwin() {
  window.open ("page.html", "newwindow", "height=100, width=100, top=0, left=0,toolbar=no, menubar=no, scrollbars=no, resizable=no, location=n o, status=no")//写成一行
  window.open ("page2.html", "newwindow2", "height=100, width=100, top=1 00, left=100,toolbar=no, menubar=no, scrollbars=no, resizable=no, loca tion=no, status=no")//写成一行
  }
  //-->
  </script>
  为避免弹出的2个窗口覆盖,用top和left控制一下弹出的位置不要相互覆盖即可 。最后用上面说过的四种方法调用即可。
  注意:2个窗口的name(newwindows和newwindow2)不要相同,或者干脆全部为空。
 
  【5、主窗口打开文件1.htm,同时弹出小窗口page.html】

  如下代码加入主窗口<head>区:

  <script language="javascript">
  <!--
  function openwin() {
  window.open("page.html","","width=200,height=200")
  }
  //-->
  </script>
  加入<body>区:
  <a href="1.htm" onclick="openwin()">open</a>即可。

 
  【6、弹出的窗口之定时关闭控制】
  
  下面我们再对弹出的窗口进行一些控制,效果就更好了。如果我们再将一小段 代码加入弹出的页面(注意是加入page.html的HTML中,可不是主页面中,否则 ...),让它10秒后自动关闭是不是更酷了?
首先,将如下代码加入page.html文件的<head>区:
  <script language="JavaScript">
  function closeit()
  {
  setTimeout("self.close()",10000) //毫秒
  }
  </script>
  然后,再用<body onload="closeit()"> 这一句话代替page.html中原有的<BODY>这一句就可以了。(这一句话千万不要忘记写啊!这一句的作用是调用关闭窗 口的代码,10秒钟后就自行关闭该窗口。)

  【7、在弹出窗口中加上一个关闭按钮】

  <FORM>
  <INPUT TYPE='BUTTON' VALUE='关闭' onClick='window.close()'>
  </FORM>
  呵呵,现在更加完美了!

  【8、内包含的弹出窗口-一个页面两个窗口】

  上面的例子都包含两个窗口,一个是主窗口,另一个是弹出的小窗口。通过下面的例子,你可以在一个页面内完成上面的效果。

  <html>
  <head>
  <SCRIPT LANGUAGE="JavaScript">
  function openwin()
  {
  OpenWindow=window.open("", "newwin", "height=250, width=250,toolbar=no ,scrollbars="+scroll+",menubar=no");
  //写成一行
  OpenWindow.document.write("<TITLE>例子</TITLE>")
  OpenWindow.document.write("<BODY BGCOLOR=#ffffff>")
  OpenWindow.document.write("<h1>Hello!</h1>")
  OpenWindow.document.write("New window opened!")
  OpenWindow.document.write("</BODY>")
  OpenWindow.document.write("</HTML>")
  OpenWindow.document.close()
  }
  </SCRIPT>
  </head>
  <body>
  <a href="#" onclick="openwin()">打开一个窗口</a>
  <input type="button" onclick="openwin()" value="打开窗口">
  </body>
  </html>

  看看OpenWindow.document.write()里面的代码不就是标准的HTML吗?只要按照 格式写更多的行即可。千万注意多一个标签或少一个标签就会出现错误。记得用 OpenWindow.document.close()结束啊。

  【9、终极应用--弹出的窗口之Cookie控制】

  回想一下,上面的弹出窗口虽然酷,但是有一点小毛病(沉浸在喜悦之中,一定 没有发现吧?)比如你将上面的脚本放在一个需要频繁经过的页面里(例如首页),那么每次刷新这个页面,窗口都会弹出一次,是不是非常烦人?:-(
  有解决的办法吗?Yes! ;-) Follow me.我们使用cookie来控制一下就可以了。
  首先,将如下代码加入主页面HTML的<HEAD>区:

  <script>
  function openwin(){
  window.open("page.html","","width=200,height=200")
  }
  function get_cookie(Name) {
  var search = Name + "="
  var returnvalue = "";
  if (document.cookie.length > 0) {
  offset = document.cookie.indexOf(search)
  if (offset != -1) {
  offset += search.length
  end = document.cookie.indexOf(";", offset);
  if (end == -1)
  end = document.cookie.length;
  returnvalue=unescape(document.cookie.substring(offset, end))
  }
  }
  return returnvalue;
  }  
  function loadpopup(){
  if (get_cookie('popped')==''){
  openwin()
  document.cookie="popped=yes"
  }
  }
  </script>

  然后,用<body onload="loadpopup()">(注意不是openwin而是loadpop啊!)替换主页面中原有的<BODY>这一句即可。你可以试着刷新一下这个页面或重新进 入该页面,窗口再也不会弹出了。真正的Pop-Only-Once!

  写到这里弹出窗口的制作和应用技巧基本上算是完成了

posted @ 2008-06-07 21:19 赵晓雷 阅读(45) | 评论 (0)编辑