关于c sharp的一系列文献
2024-07-21 02:20:12
供稿:网友
注册会员,创建你的web开发资料库,microsoft正在紧锣密鼓地计划推出visual studio 6.0的下一代产品——visual studio.net。对于这个软件包大家谈论最多的除了.net外,要数它的另外一个利器c#。由于不准备在visual studio.net中包括visual j++,c#应该算是微软针对java的相应产品。那么,什么是c#?它和c、c++究竟有什么不同?在此,我们归纳了一些关于c#常见的问题及解答,旨在帮助不了解它的读者对它有个初步的认识。由于c#更多地类似c++,所以在此主要和c++做一对比。
概述
1. 什么是c#?
c#是microsoft公司设计的一种编程语言。它松散地基于c/c++,并且有很多方面和java类似。microsoft是这样描述c#的:“c#是从c和c++派生来的一种简单、现代、面向对象和类型安全的编程语言。c#(读做‘csharp’)主要是从c/c++编程语言家族移植过来的,c和c++的程序员会马上熟悉它。c#试图结合visual basic的快速开发能力和c++的强大灵活的能力。”
2. 什么时候c#发布?
没有准确的时间,但是希望在2001年下半年。
3. 如何开发c#应用程序?
.net sdk包括了c#命令行编译器(csc.exe),下一个版本的visual studio (visual studio 7 or visual studio.net)会包含对c#开发的完整支持。
4. 我从哪里可以下载.net sdk & visual studio 7?
你可以在http: //msdn.microsoft.com/net下载sdk的beta 2版本。如果你是一个msdn universal的定户,你可以下载visual studio 7 beta 2。
5. c#可以取代java?
c#非常像java语言——这两种语言的核心和c++相比都有相似的优缺点。例如,两个语言都有垃圾回收,但是两个语言都没有模板(template)。microsoft已经中止了visual j++产品,因此很难不认为microsoft在使用c#来替代java。
6. c#可以取代 c++?
显然是不,但是我们又很难说c++是新的.net平台上编写代码的最佳选择。为了使.net的运行层能完全发挥作用,它要求编程语言遵循某些特定的规则——其中之一就是所有的语言类型必须遵守通用类型系统(common type system,cts)。不幸的是,许多c++特性不能被cts支持。例如,模板和类的多重继承。
microsoft对这个问题的答案是给c++提供可管理的扩展(managed extensions,me), 这可以使c++遵守cts。通过添加新的关键字来标记c++类有cts的属性(例如.-gc表示垃圾回收)。但是在创建新的工程时很难讲为什么me c++会比c#更合适。就特征(feature)而言它们很相似,但与c++不同的是c#从一开始就以.net为环境设计的。me c++存在的理由好像是将c++代码移植(port)为.net环境下的代码。
因此,这个问题的答案,很可能是c++作为一个.net环境之外的语言将依然保留它的重要性;而通过me将现存的c++代码移植为适合.net环境;但是很可能c#将是c++开发者开发新的.net应用程序的最好选择。
7. 一个简单的c#程序是怎样的?
可以是这样:
class capplication {
public static void main() {
system.console.write( “hello, new .net world!” ); }}
(你不能将main()作为全局函数——c#没有全局函数)
8. c#是面向对象的吗?
是的,c#像java和c++一样,是一个面向对象的语言。
9. c#有自己的类库吗?
不,就像所有的.net语言(vb.net,jscript
.net...)一样,c#访问.net类库,c#没有自己的类库。
基本类型
1. c#提供什么标准类型?
c# 支持的基本类型和c++很相似,包括int, long, float, double, char, string, arrays, structs 和 classes。然而,不要假设太多,名字可能很形似,但是一些细节不相同。例如c#中的long是64位的,而c++的long取决于平台,32位的平台上是32位的,64位的平台上是64位的。class和struct在c++中几乎完全一样,但在c#中并不是这样的。
2. 是否所有的c#类型都派生于一个公共的基类?
是,也不是,所有的对象都可以看作从object (system.object)派生而来。但是为了把像int,float这样的值类型实例看作是从object对象派生的,这个实例必须通过一个装箱的操作(boxing)转化为引用类型。理论上,开发者可以忽略这些底层的转化,但是认识到这点对于系统性能影响很重要。
3. 是否可以这样认为,可以将一个值类型的实例作为参数传给以对象为参数的方法?
是的,例如:
class capplication {
public static void main() {
int x = 25;
string s = “fred”;
displayme( x );
displayme( s ); }
static void displayme( object o ) {
system.console.writeline( “you are {0}”, o ); }}
将显示:
you are 25
you are fred
4. 值类型和引用类型的最基本的区别是什么?
c#将类型分为两类,一类是值类型,另一类是引用类型。大部分固有的基本类型(如int, char)是值类型,structs 也是值类型。引用类型包括类、接口、数组和字符串。基本的概念非常简单,那就是一个值类型的实例代表了实际的数据(存在栈中),而一个引用类型的实例代表指向数据的指针或者引用(存在堆中)。
c++开发者最容易混淆的地方是:c#已经自己预定义了一些类型作为值类型,一些作为引用类型,而一个c++的开发者希望能够自己控制。
例如,在c++中,我们可以这样做:
int x1 = 3; // x1 是堆栈上的值
int *x2 = new int(3) // x2 是堆的一个值的引用
但是在c#中没有这样的控制:
int x1 = 3; // x1是堆栈上的值
int x2 = new int();
x2 = 3; // x2还是堆栈上的值!
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++ 构造器是否相同?
非常相似。
5. 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#类中,然后就可以知道是如何编译的了。
6. 如果c#析构器不同于c++析构器,为什么使用相同的句法呢?
这确实使我们糊涂。
7. 什么是静态构造器?
它是整个类的一个构造器,而不是类的一个实例的构造器,它在类装载的时候被调用。
8. c#中所有的方法都是虚方法吗?
不,像c++一样,缺省的时候,方法不是虚拟的,但都可以改为虚拟的。
9. 怎样在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位的。