新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论.NET,C#,ASP,VB技术
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 Dot NET,C#,ASP,VB 』 → 包装很好,里面是什么? (转载) 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 2244 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 包装很好,里面是什么? (转载) 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     admin 帅哥哟,离线,有人找我吗?
      
      
      
      威望:9
      头衔:W3China站长
      等级:计算机硕士学位(管理员)
      文章:5255
      积分:18406
      门派:W3CHINA.ORG
      注册:2003/10/5

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给admin发送一个短消息 把admin加入好友 查看admin的个人资料 搜索admin在『 Dot NET,C#,ASP,VB 』的所有贴子 点击这里发送电邮给admin  访问admin的主页 引用回复这个贴子 回复这个贴子 查看admin的博客楼主
    发贴心情 包装很好,里面是什么? (转载)


    发信人: Jobs (温少), 信区: DotNET        
    标  题: 包装很好,里面是什么? (转载)
    发信站: BBS 水木清华站 (Wed May  2 00:49:49 2001)


    包装很好,里面是什么?  
    作者:Eric Gunnerson

    原文URL:http://www.microsoft.com/china/msdn/voices/csharp02152001.asp

    C# 中的类型
    C# 和公共语言运行时 (CLR) 中有两种类型:引用类型(在 C# 中用类声明)和值
    类型(在 C# 中用结构声明)。引用和值类型在几个重要方面有所不同。下表概括
    了这些区别:

                    引用(类)              值(结构)  

    保留变量        引用                    实际值  
    活动值          在堆中                  内联(在堆栈中或与对象内联)  
    默认值          Null                    零  
    = 表示          复制引用                复制值  

    值类型“感觉上”象一个数据。它包括预定义数值类型以及用户定义的类型(如  
    Complex 数字、Point 或 Rectangle)。如上文所述,值类型的变量是实际的值,
    所以在您使用变量时,通常处理的是实际的值。

    int i = 123;
    int j = i;
    i = 55;

    在第二次指定变量后,两个独立的变量包含相同的值。修改 i 的值不会改变 j 的
    值。

    引用类型用于所有不能用作值类型的对象。引用类型的变量指向堆中对象的实例。
    这意味着在将一个变量指定给另一个变量时,只是指定了引用,而不是值。

    Employee e = new Employee("Fred");
    Employee f = e;
    f.Name = "Barney";

    在第二次指定变量后,e 和 f 指向同一对象。这意味着修改 f 的名称也将改变 e
    的名称,因为它们引用同一实例。

    这引发了一个相关话题。有些人可能一直奇怪,为什么 System.String 类中的函
    数不修改字符串,而总是返回字符串的新副本。这是因为字符串的类型为引用类型
    。如果对字符串调用 s.Trim() 来修改内部字符串,您将遇到与 Employee 相同的
    问题(这对字符串非常糟糕)。

    修改类值的成员称为“变更者”,而不具有任何变更者的类称为不可变类。不可变
    类的存在可以使类的行为类似于值类,但不能写入为值类。

    如果您需要使用可变字符串类,请在 System.Text 中试用 StringBuilder。  


    转向更简单的模型
    在语言中同时使用引用和值两种类型是很重要的。值类型轻便高效,而引用类型适
    用于面向对象的开发。但是,现在我们有两种类型,而我们需要的是更为简单的模
    型,使用单一的、能够囊括所有可能值的类型。

    这样一个通用基类能够:

    调用任何值的虚函数。


    写入能够存储任何值的集合类。


    替代 OLE Automation Variant 类型。  
    为实现这一目的,公共语言运行时采用一种方法让值类型在需要时转化为引用类型
    ,即通过称为包装的进程。被包装的类型是通用基类,可以被各种类型的对象引用




    包装和解除包装

    考虑下列代码:

    int value = 123;
    object o = value;   // 将 int 包装到对象中
    int value2 = (int) o;   // 解除包装到 value2

    当赋值给 o 时,作为赋值的一部分,C# 编译器将创建足够容纳堆中 int 的引用
    类型包装,将值复制到该包装,然后将包装标记为实际类型(此处为 System.
    Int32),以便运行时了解包装的类型。

    要从包装中取值,必须使用强制类型装换来指定包装的类型(对象能够保留任何类
    型)。在执行过程中,运行时将检查对象变量引用的类型是否为强制类型转换中指
    定的类型。如果类型正确,值将从包装中复制回值类型变量。如果类型不正确,将
    导致异常。

    请注意解除包装过程中不会进行其他转换;类型必须完全匹配。换句话说,如果我
    们编写代码:

    long value2 = (long) o;   // 包装的值是 int

    其中 o 为已包装的 int,则将导致异常。但是,我们可以这样编写:

    long value2 = (long)(int) o;

    则转换将正常进行。

    虽然这个示例演示了包装和解除包装,但可能会造成一些误解。编写代码进行包装
    的情况非常少见,一般是在将值类型的变量传递给类型对象参数时使用。

    下面是一个小测验。希望大家用心做。

    测验:您对包装了解多少?
    下面的代码段给出了不同方案。请阅读这些代码,判断哪一段代码涉及包装,而哪
    一段与包装无关。有些方案(如 B)需要检查多个位置。

    // 方案 1
    int total = 35;
    DateTime date = DateTime.Now;
    string s = String.Format("Your total was {0} on {1}", total, date);

    // 方案 B
    Hashtable t = new Hashtable();
    t.Add(0, "zero");
    t.Add(1, "one");

    // 方案 c
    DateTime d = DateTime.Now;
    String s = d.ToString();

    // 方案 IV
    int[] a = new int[2];
    a[0] = 33;
      

    // 方案 101
    ArrayList a = new ArrayList();
    a.Add(33);

    // 方案 vi
    MyStruct s = new MyStruct(15);
    IProcess ip = (IProcess) s;
    ip.Process();

    答案
    请检查答案并记录分数。

    方案 1
    String.Format() 将字符串作为第一个参数,对象作为第二个和第三个参数。
    int 和 DateTime 都是值类型,所以它们都将被包装以作为第二个和第三个参数。
    String.Format() 使用这些参数,然后对每个参数调用 object.ToString() 将其
    转换为字符串表示。如果您知道 int 将被包装,得一分;如果知道 DateTime 被
    包装,得一分。

    方案 B
    Hashtable.Add() 有两个参数,一个是关键字,另一个是值。它们都是类型对象。
    传递给关键字参数的值为整数,所以它必须被包装,才能作为对象传递。传递给值
    参数的值为字符串(引用类型),所以字符串不需要包装。每一点判断正确各得一
    分。

    方案 c
    这段代码很迷惑人。包装的目的之一是实现对值类型参数的虚函数调用。
    ToString() 是对象的虚函数,所以,看起来在调用 ToString() 时,d 将被包装
    。但是在转换对象时没有使用 d,所以不需要进行包装。编译器知道类型为  
    DateTime 的变量只能为该类型(因为没有导出的值类型,所以该变量不能为导出
    类型),所以它可以直接调用 DateTime.ToString(),并设置“这个”引用,使其
    指向堆栈中的 d。如果回答正确,得一分。

    方案 IV
    CLR 中的数组直接保存它们的值。例如,一个有五个元素的 int 数组有足够的空
    间保存 5 个 int,而不是 5 个对象。如果认为此代码与包装无关,得一分。

    方案 101
    ArrayList.Add() 将对象作为参数,所以整数 33 将被包装。如果回答正确,得一
    分。

    方案 vi
    接口为引用类型,所以在将值类型强制转换到接口实现时,必须包装值类型。如果
    了解这一点,得一分。

    最后得分

    将所有分数相加,并使用下表来检查对包装的了解程度:

            分数            说明  
            8               对包装很了解  
            6-7             了解,但有时明白,有时糊涂  
            3-5             尚可,请再接再厉  
            1-2             需要继续学习  
            0               尚未入门  



    摘要
    最后总结一下包装。包装使编写和使用具有通用对象参数的函数变得简单而直接。
    和许多美好的事情一样,包装也有不好的一面。下个月,我们将讨论这些不好的方
    面是什么,如何减少负面影响,以及对 C# 的进一步说明(这会让我们的 C# 生活
    更加美好)。

    C# Web 站点荟萃

    http://www.csharphelp.com
    http://dotnetwire.com

    --

    ※ 来源:·BBS 水木清华站 smth.org·[FROM: 210.39.3.110]
    返回上一页
    回到目录
    回到页首
    下一篇


       收藏   分享  
    顶(0)
      




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

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

    第十二章第一节《用ROR创建面向资源的服务》
    第十二章第二节《用Restlet创建面向资源的服务》
    第三章《REST式服务有什么不同》
    InfoQ SOA首席编辑胡键评《RESTful Web Services中文版》
    [InfoQ文章]解答有关REST的十点疑惑

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2004/11/9 2:25:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 Dot NET,C#,ASP,VB 』的所有贴子 点击这里发送电邮给Google AdSense  访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/5/16 18:59:08

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    3,296.875ms