FAQ

原创 2004年09月16日 14:02:00

问:为什么引用类型不是多态类型?

答:请考虑以下代码:

using System;
class Dog {
   public string Name;
}
class Test
{
   public static void Swap(ref object a, ref object b) {
      object temp;
      temp = a;
      a = b;
      b = temp;
   }
   public static void Main() {
      Dog d1 = new Dog();
      d1.Name = "fido";
      Dog d2 = new Dog();
      d2.Name = "rex";
      Swap(ref d1, ref d2);
   }
}

编译器将对 Swap() 函数调用时报告错误。为什么?请考虑 Swap 函数采用以下形式的情况:

public static void Swap(ref object a, ref object b) {
      a = 5;
      b = “Hello“;
   }

如果编译器允许使用上述代码,这将意味着将装箱的 int 类型值赋给 Dog 对象,这显然不是类型安全的。

[作者:Eric Gunnerson]

发布时间:2004 4 8 14:55:00 GMT 星期四    评论(11)

返回页首返回页首

什么时候应该使用 ==?什么时候应该使用 Equals?

Equals 方法只是在 System.Object 中定义的一个虚拟方法,它由任何选择执行该任务的类所重写。== 运算符是一个可由类重载的运算符,该类通常具有恒等行为。

对于未重载 == 的引用类型,该运算符会比较两个引用类型是否引用同一对象,而这恰好是 System.Object 中的 Equals 实现所做的工作。

对于未重载 == 的值类型,该运算符会比较这两个值是否"按位"相等,即是否这两个值中的每个字段都相等。当您对值类型调用 Equals 时,仍然会发生这一情况,但这一次,该实现是由 ValueType 提供的,并且使用反射进行比较,从而使比较速度比特定于类型的实现慢很多。

到此为止,二者是如此类似。二者之间的主要区别是多态。运算符被重载而不是被重写,这意味着除非编译器知道调用更为具体的版本,否则它只是调用恒等版本。为阐明这一点,请看下面这个示例:

using System;
public class Test
{
static void Main()
{
        // Create two equal but distinct strings
        string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
        string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
        Console.WriteLine (a==b);
        Console.WriteLine (a.Equals(b));
        // Now let's see what happens with the same tests but
        // with variables of type object
        object c = a;
        object d = b;
        Console.WriteLine (c==d);
        Console.WriteLine (c.Equals(d));
    }
}

结果是:

True
True
False
True

第三行是 False,原因在于编译器不知道 c 和 d 的内容都是字符串引用,因而只能调用 == 的非重载版本。因为它们是对不同字符串的引用,所以恒等运算符返回 False。

那么,应该如何区别使用这些运算符呢?我的准则是:对于几乎所有引用类型,当您希望测试相等性而不是引用一致性时,请使用 Equals。例外的情况是字符串 - 使用 == 比较字符串确实会使事情简单得多,而且代码可读性更好,但是 您需要记住,该运算符的两端都必须是类型字符串表达式,才能使比较正常进行。

对于值类型,我通常使用 ==,因为除非值类型本身包含引用类型(这种情况极为罕见),否则是恒等还是相等的问题无关紧要。

[作者:Jon Skeet]

发布时间:2004 3 29 15:56:00 GMT 星期一    评论(2)

返回页首返回页首

我应该将 null 赋给局部变量吗?

问:在我使用局部变量以后,应该将 null 赋给它们吗?

例如:

string s = ...;
Console.WriteLine(s);
s = null;

答:在 C# 中,很少需要对局部变量执行该操作。

变量的生存期由 JIT 跟踪,JIT 会分析变量在例程中的使用方式,准确地了解何时不再需要该变量,并且知道此后可以回收该值。

有意思的是,如果您将 null 赋给它,实际上会稍微延长该变量的生存期,从而可能导致对它进行垃圾回收的时间拖后(尽管实际上这不大可能有什么真正的区别)。

对于绝大多数方法而言,这都是真的。如果您有一个方法,该方法中的代码生存一段时间(例如,在独立的线程中执行循环),则查看一下在您等待的过程中,变量中是否有不需要的值生存可能是有意义的。

[作者:Eric Gunnerson]

发布时间:2004 3 26 12:15:00 GMT 星期五    评论(5)

返回页首返回页首

在调用委托之前,为什么需要执行 null 测试?

问:在调用委托之前,为什么需要执行 null 测试?

答:如果在类中有事件,则在调用委托之前,需要添加 null 测试。通常,您编写以下代码:

if (Click != null)
    Click(arg1, arg2);

这里实际上可能存在争用条件 - 事件可能在第一行和第二行之间被清除。您实际上希望编写以下代码:

ClickHandler handler = Click;
if (handler != null)
    handler(arg1, arg2);

(通常情况下)。在其他场合下,您可能需要进行某种其他种类的同步。

让我们回到主要问题。为什么需要进行 null 测试?

我们不能通过委托来更改调用的现有行为,因为某些应用程序可能依赖于它,所以必须对语言进行增强。

我们已经讨论过通过向语言中添加 Invoke() 关键字来使这一问题变得简单,但是在经过深入的讨论之后,我们断定我们无法做到任何时候都不犯错误,所以我们决定什么都不做。

运维路上的FAQ

遇到的看见的,长期更新~~~ 1.linux乱码问题     [root@vps software]# vi  /etc/sysconfig/i18n     LANG='zh_...
  • u010718976
  • u010718976
  • 2017年01月10日 11:00
  • 183

EGit /用户指南

EGit /用户指南 EGit 内容 1 开始 1.1 概述1.2 基本教程:项目添加到版本控制中 1.2.1 " 配置 1...
  • jibaole
  • jibaole
  • 2016年01月23日 19:33
  • 2046

数据库学习FAQ

数据库学习FAQ 简述数据、数据库、数据库管理系统、数据库系统的含义及其联系?数据:数据是信息的符号记录。数据是数据库处理和研究的对象 数据库:长期存储在计算机内,有组织、可共享的数据集合。数据按一定...
  • pupilxmk
  • pupilxmk
  • 2016年05月25日 08:59
  • 470

ARM7开发板模拟器Skyeye安装设置全攻略

本文目的:在linux里装Skyeye,用Skyeye模拟ARM7DTMI,运行uClinnux-2.4.x SkyEye可以做什么事情? 1. 通过SkyEye可以帮助促进嵌入式系统的学习,在不...
  • benjaminwan
  • benjaminwan
  • 2013年06月18日 18:15
  • 1474

Spark调研笔记第6篇 - Spark编程实战FAQ

本文主要记录我使用Spark以来遇到的一些典型问题及其解决办法,希望对遇到同样问题的同学们有所帮助。 1. Spark环境或配置相关 Q: Spark客户端配置文件spark-defaults.c...
  • slvher
  • slvher
  • 2015年06月10日 11:16
  • 1732

Linux 常用到的功能及命令-FAQ

如何查看某个进程启动多长时间了? ps -p pid -o etime= 具体参数参考 man 手册top命令 在top交互界面上,输入字母 E 可以调整总内存的显示单位,使用字...
  • It_way
  • It_way
  • 2016年06月18日 23:13
  • 237

微信小程序开发者常见FAQ之二

微信小程序遇到问题怎么办?遇到微信小程序方面的问题,该去哪里提问呢?一起来看看第九程序为您整理的微信开发者社区开发常见问题FAQ吧~在文中,您可使用「CTRL+F」,输入关键词来快速找寻您需要的答案。...
  • qq_38125123
  • qq_38125123
  • 2017年04月21日 15:02
  • 260

Spring框架简介

Spring框架是一个JAVA框架,提供了开发JAVA应用程序时所需的全面的基础架构。Spring负责基础结构所以你可以把注意力放到程序实现上。            Spring 可以使你从“简单...
  • z1049186181
  • z1049186181
  • 2016年05月18日 19:06
  • 2935

mysql使用规范

1.命名规范 (1)库名、表名、字段名必须使用驼峰命名。 (2)库名、表名、字段名禁止超过32个字符。 (3)库名、表名、字段名必须见名知意。命名与业务、产品线等相关联。 (4...
  • x1066988452
  • x1066988452
  • 2016年10月20日 16:46
  • 321

C++11 FAQ中文版

C++11 FAQ中文版 http://www.chenlq.net/cpp11-faq-chs http://www.stroustrup.com/C++11FAQ....
  • bamboolsu
  • bamboolsu
  • 2015年03月20日 17:41
  • 1507
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:FAQ
举报原因:
原因补充:

(最多只允许输入30个字)