科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件C#语言基础常见问题汇总(2)

C#语言基础常见问题汇总(2)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

既然 int是值类型,而 class是引用类型,那么int是怎样从Object派生的呢?

来源:soft6 2008年5月16日

关键字: 问题 基础 C# Windows

  • 评论
  • 分享微博
  • 分享邮件

5. 既然 int是值类型,而 class是引用类型,那么int是怎样从Object派生的呢?   

是这样的,当int用作int时候,这是一个值类型(在栈上),然而,当它用作是Object时,这是一个引用堆上的整数值的引用类型。换而言之,当你将int看作对象时,运行层将它自动转化为对象引用,这个转化过程称作装箱(boxing)。这个转换包括将栈里的值拷贝到了堆里,并且新建了一个对象的实例来引用该值。拆箱操作(unboxing)是个反过程——将对象转化为基于栈的值类型。

int x = 3;

// 堆栈上新的int类型,值为3

object objx = x;

// 堆上新的int, 设定值为3,x=3仍然在堆栈上

int y = (int)objx;

//新的int类型的值3在堆栈上,x=3在堆栈上,objx=3在堆上

6. C#使用引用替代指针,那么C#的引用和C++的引用一样吗?   

不完全,基本的思想是一样的,但是一个重要的区别是C#的引用可以是null。因此你不能确认C#的引用一定会是一个有效的对象。如果试图使用一个值为null的引用,一个NullReferenceException 异常将被抛出。

 

例如,看一看以下的方法:

void displayStringLength( string s ) {

Console.WriteLine( “String is length {0}”, s.Length ); }

如果这样调用它,这种方法将产生一个NullReferenceException 异常:

string s = null;

displayStringLength( s );

当然有些情况你认为产生这样一个异常是完全可以接受的结果,但是在这个例子里最好按下面的代码改写一下:

void displayStringLength( string s ) {

if( s == null )

Console.WriteLine(“String is null”);

else

Console.WriteLine(“String is length {0}”, s.Length );

}

class和struct

1. struct在C++中是多余的,为什么C#还要使用它们呢?   

在C++中,一个结构和一个类几乎就是一个同样的东西。唯一的区别是缺省的成员的访问级别不一样(struct的缺省级别是public,class的缺省级别是private)。然而,在C#中struct和class完全不一样。在C#中,struct 是值类型,而class是引用类型。另外struct不能从其他struct或者class继承,尽管struct可以实现接口。struct没有析构器。

2. C#支持多重继承吗?   

C#支持接口的多重继承,但是不支持类的多重继承。

3. C#接口和C++抽象类一样吗?   

不,不完全。C++的抽象类不能被实例化。但是它可以(而且经常是)包含执行代码和数据成员。一个C#接口不能包含任何执行代码或数据成员,它只是一组方法名称和签名(signature)。一个C#的接口更像是一个COM接口而不是抽象类。

另一个主要的不同点是:C#类只能从一个类(不管是否抽象)继承,但可以实现多重接口。

4. C#构造器和C++ 构造器是否相同?   

非常相似,但是它们绝对不同。第一,C#析构器不保证在某个特定的时间被调用。实际上它根本不保证被调用。真实的情况是,C#析构器只是一个伪装了的Finalize方法。具体点讲,它是一个插入调用基类Finalize方法的Finalize方法。因此,这段代码:

class CTest {

~CTest() {

System.Console.WriteLine(“Bye bye” );

}

}

实际上就是:

class CTest {

protected override void Finalize() {

System.Console.WriteLine(“Bye bye” );

base.Finalize();

}  

}

如果你不相信,可以将一个 Finalize方法和一个析构器加入C#类中,然后就可以知道是如何编译的了。

5. 什么是静态构造器?   

它是整个类的一个构造器,而不是类的一个实例的构造器,它在类装载的时候被调用。

6. C#中所有的方法都是虚方法吗?   

不,像C++一样,缺省的时候,方法不是虚拟的,但都可以改为虚拟的。

7. 怎样在C#中声明一个纯虚函数?   

在方法前使用abstract修饰符,类也可以标记为abstract(这是自然的)。注意,abstract方法不能有执行代码(不同于C++中纯虚方法)。
和C++处理的不同

1. 我“new”了一个对象,但是我怎样删除它?   

你不能,不允许你显式地调用析构器,也没有delete操作符。但是不必担心,垃圾回收(garbage collection)会释放你的对象,最终会的(也许会的)。

2. 我试图在栈上建立一个对象,但是C#编译器不通过,这是怎么回事?   

和C++不同,你不能在栈上建立一个对象的实例。类的实例总是被建立在堆上并且接受垃圾回收器(garbage collection)的管理。

3. 我定义了一个析构器,但是它从来不能被调用,为什么?   

一个C#析构器实际上是Finalize方法的实现,但是运行环境不保证调用Finalize方法。你可以考虑通过调用GC.RequestFinalizeOnShutdown()方法试一下。

4. 大多数的C#基本类型和C++的基本类型有相同的名字,它们一样吗?   

不,C#中char和C++中的wchar是相同的。C#中所有的字符包括字符串都是Unicode的,C#中整型值是固定大小的,而在C++中其大小取决于处理器。例如,一个C#的int是32位的,而C++ 中int在32-bit处理器上是32位的,在64-bit处理器上是64位的,一个C#的long是64位的。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章