2024年5月25日发(作者:)

文档供参考,可复制、编制,期待您的好评与关注!

1.面向对象的思想主要包括什么?

答:个人认为一各程序语言要成为真正的面向对象的程序设计语言,它必须符合下列条件:

1抽象(abstraction)—抽象能够有效地管理一个问题的复杂性,其作法是划分出与该问

题相关的一组对象.

2 封装(Encapsulation)—封装是指将一个抽象的内部实现隐藏在特定的对象之内.

3 多态(polymorphism)—多态会提供相同方法的多种操作方法的多种操作实作.例如,

不同的对象都会拥有一个Save方法,但是每一个Save方法会执行不同的操作.

4 继承(inheritance)—Visual C# 2005 最令人兴奋之处就是其继承特性.v c#2005则

提供了真正的方法继承,因此您可以重复使用一个类的实例.

2.什么是中的用户控件

自己动手作自己的控件来取代.NET提供的控件。这种控件就是用户控件。

后缀

为.ascx

3.什么叫应用程序域?什么是受管制的代码?什么是强类型系统?什么是装箱和拆箱?什

么是重载?什么是多态? CTS、CLS和CLR分别作何解释?

应用程序域:应用程序域(通常是 AppDomain)是用于隔离应用程序的虚拟进程。在同

一个应用程序作用域中创建的所有对象(换句话说,从该应用程序的入口点开始沿着对象

激活序列的任何地方)都在同一个应用程序域中创建。多个应用程序域可以存在于一个操

作系统进程中,使它们成为隔离应用程序的简便方式。 操作系统进程通过使用各不相同的

内存地址空间来提供隔离。尽管它是有效的,但也是代价昂贵的,并且不能达到大型 Web

服务器所需要的数量。与其相比,公共语言运行时通过管理在应用程序域中运行的代码的

内存使用来强制进行应用程序隔离。这样就确保它不会访问应用程序域以外的内存。需要

注意的是,只有类型安全的代码才能以这种方式管理(当在应用程序域中加载不安全代码

时,运行时不能保证隔离)。

理解应用程序域:

应用程序域是.NET 运行库的逻辑进程表示,操作系统进程可以包含多个应用程序域。应用程序

域具有下列优点:

1、隐藏了进程具体的操作系统信息。从而允许把.NET 放在不同的操作系统下。

2、提供了隔离。即使运行在同一个进程中的属于不同域的应用程序也不能直接共享全局数据、

静态数据或其他资源。所以,一个应用程序域失败了,也不会影响到同一个进程中的其他应用

程序域。

3、对于不需要昂贵的 IPC 机制的进程,应用程序域允许 .NET 运行库优化运行在这种进程中

的应用程序间的通信。

因为应用程序域是被隔离的,所有.NET 对象都会被界定在创建它的应用程序域内。如果跨应用

程序域的边界传递对象引用,该被引用对象就被称为远程对象。

装箱和拆箱

在C#中的有两种类型的变量:值类型和引用类型。当值类型和引用类型相互转化时,会发生装

箱和拆箱的过程。这里有一点要声明:经过拆箱或装箱的对象会多出它自己一份拷贝。它和它的

1 / 59

文档供参考,可复制、编制,期待您的好评与关注!

拷贝不在一个存储区域。这也是值类型和引用类型的区别所在。值类型总是在栈中,而引用类

型总是在托管堆中。(目前J2SE5.0也支持了装箱和拆箱,但是我目前不知道是否和C#一样)。

为了进一步理解看下面例子:

struct Point{

public int x;

public int y;

}

static void Main(){

Point p;

p.x=10;

p.y=20;

Object o=p;//box. 将值类型从栈中拷贝到堆中。

/************************************************************************/

* 从托管堆中将对象拷贝到栈中。

/************************************************************************/

Point p2=(Point)p;

ine(“p2.x:="+p2.x+ “ p2.y:=“+p2.x);

p.x=16;

p.y=34;

ine(“p2.x:="+p2.x+ “ p2.y:=“+p2.x);

ine(“p.x:="+p.x+ “ p.y:=“+p.x);

}

输出结果为:

p2.x:=10;p2.y=20;

p2.x:=10;p2.y=20;

p.x:=16;p.y=34;

可知,变量经过拆箱/装箱后,得到是自己的另一份拷贝。

装箱和取消装箱的概念是 C# 的类型系统的核心。它在“值类型”和“引用类型”之间的架起了

一座桥梁,使得任何“值类型”的值都可以转换为 object 类型的值,反过来转换也可以。装

箱和取消装箱使我们能够统一地来考察类型系统,其中任何类型的值最终都可以按对象处理

多态

一.形象理解

两条理解的原则:

(1)一个派生类对象可以被声明成一个基类,或者是一个基类指针可以指向一个派生类对象:

//c++ code

BaseClass *p;

DerivedClass obj;

p = &obj;

2 / 59

文档供参考,可复制、编制,期待您的好评与关注!

//C# code

BaseClass obj = new DerivedClass();

(2)把一个对象看做是一个独立的个体,调用对象的public成员函数实际上是给这个对象发送

一个消息,采取什么样的动作完全由对象自己决定。

Shape是基类,Circle和Line是从Shape继承出来的,Shape有draw()方法,Circle与Line分别自

己定义了自己的draw()方法,在下面的代码里:

// Java Code

static void func(Shape s)

{

();

}

如果发生了这样的调用:

Line l = new Line();

Circle c = new Circle();

func(l);

func( c);

一个Circle和一个Line被当做Shape传到函数里去了,然后调用Draw(),会发生什么情况?因为

对象是独立的个体,在func()里,这两个对象被分别传递了Draw()消息,叫它们绘制自己吧,

于是他们分别调用了自己类里定义的Draw()动作。

通过这两条原则我们可以理解上面的多态。正是由于多态,使得我们不必要这样去做:

IF 你是一个Circle THEN 调用Circle的Draw()

ELSE IF 你是一个Line THEN 调用Line的Draw()

ELSE …

我们只要给这个被声明成为Shape的对象发送Draw消息,怎么样去Draw就由对象自己去决定了。

二.一切皆因虚函数

先看看实现多态的基本条件:

(1) 基类含有虚函数

(2) 继承类把这个虚函数重新实现了

(3) 继承类也可能没有重新实现基类的所有虚函数,因此对于这些没有被重新实现的

虚函数不能发生多态。

再看一下几种语言里一些特别的规定:

1. C++:

(1)虚函数用virtual关键字声明。

(2)virtual void Func(para_list) = 0;这样的虚函数叫做纯虚函数,表示这个函数没有具

体实现。包含纯虚函数的类叫做抽象类,如果他的继承类没有对这个纯虚函数具体用代码实现,

则这个继承类也是抽象类。抽象类不能被实例话(就是说不能创建出对象)。

(3)继承类重新实现基类的虚函数时,不需要做任何特别的声明。

(4)如果不用virtual关键字修饰,并且在派生类里重新实现了这个方法,这仅仅是一个简单

3 / 59

文档供参考,可复制、编制,期待您的好评与关注!

的覆盖,不会发生多态,我们暂称它非多态吧。

2. Java:

(1)Java没有virtual关键字,Java把一切类的方法都认为是虚函数。

(2)继承类重新实现基类的虚函数时,不需要做任何特别的声明。因此在Java里只要重新实现

了基类的方法,并且把继承类对象声明为基类,多态就要发生。因此Java对多态的条件相对是

比较低的。

//Java Code

class BaseClass

{

public void hello(){};

}

class DerivedClass extends BaseClass

{

public void hello()

{

n(“Hello world!”);

}

public static void main(String args[])

{

BaseClass obj = new DerivedClass();

();

}

}

输入是Hello world!。这样就实现了多态。

(3)虚函数用abstract声明,含有虚函数的类是抽象类,也要用abstract关键字修饰。

//Java Code

public abstract AbstractClass

{

public abstract void hello();

//…

}

3. C#:

C#对于多态的编写是最为严格和严谨的。

(1)虚函数用virtual声明。

(2)纯虚函数用abstract声明,含纯虚函数的类是抽象类,必须用abstract关键字修饰。

(3)如果仅仅是覆盖基类的非虚方法,则需要用new关键字声明:

//C# Code

public class BaseClass

4 / 59

文档供参考,可复制、编制,期待您的好评与关注!

{

public void hello()

{

ine(“Hello,this come from BaseClass”);

}

}

public class DerivedClass : BaseClass

{

public new void hello()

{

ine(“Hello,this is come from DerivedClass”);

}

public static void Main()

{

BaseClass obj = new DerivedClass();

();

}

}

输出为Hello,this come from BaseClass,也就是说这并没有实现多态(非多态)。

(4)通过virtual – override、abstract – override组合实现多态。

当派生类重新实现基类的虚函数(或纯虚函数)时,必须用override关键字进行修饰。

//C# Code

public abstract class AbsBaseClass

{

public abstract void hello();

}

public class DerivedClass : AbsBaseClass

{

public void hello()

{

ine(“Hello world!”);

}

public static void SayHello(AbsBaseClass obj)

{

();

}

public static void Main()

{

5 / 59

文档供参考,可复制、编制,期待您的好评与关注!

DerivedClass _obj = new DerivedClass();

lo(_obj);

}

}

输出为Hello world!

三.多态的反溯

继承类对象在发生多态时,并是不完全抛开基类不管的,它会去查看基类的虚函数列表,在这

个列表的范围内才会发生多态。

让我们来看一个比较复杂的例子:

// Java Code

class A

{

protected void hello(Object o)

{

n("A - Object");

}

}

class B extends A

{

protected void hello(String s)

{

n("B - String");

}

protected void hello(Object o)

{

n("B - Object");

}

};

class C

{

public static void main(String args[])

{

Object obj = new Object();

String str = "ABC";

A a = new B();

(obj);

(str);

}

6 / 59

文档供参考,可复制、编制,期待您的好评与关注!

};

输出结果为:

B – Object

B – Object

正如上面所说的,由于基类里没有参数类型为String的虚函数,因此B的hello(String)方法不

参与多态。调用(str)时,由于String是Object的继承类,因此这个str被作为一个Object

传入了B的hello(Object),这一点正如我们的原则一所述。

四.接口——仅仅是更抽象的抽象类

接口是类的协定,但由于接口又参与多态性,从这一点说,我们认为它是更为抽象的抽

象类:

CTS、CLS和CLR

.NET结合Java和COM解决方案两者优点来解决互操作性问题。类似于COM定义的标准二进制

格式,.NET定义了一个称为通用类型系统Common Type System(CTS)的类型标准。这个类型

系统不但实现了COM的变量兼容类型,而且还定义了通过用户自定义类型的方式来进行类型

扩展。任何以.NET平台作为目标的语言必须建立它的数据类型与CTS的类型间的映射。所

有.NET语言共享这一类型系统,实现它们之间无缝的互操作。该方案还提供了语言之间的

继承性。例如,用户能够在中派生一个由C#编写的类。

很显然,编程语言的区别不仅仅在于类型。例如,一些语言支持多继承性,一些语言支持

无符号数据类型,一些语言支持运算符重载。用户应认识到这一点,因此.NET通过定义公

共语言规范(CLS:Common Language Specification),限制了由这些不同引发的互操作性

问题。CLS制定了一种以.NET平台为目标的语言所必须支持的最小特征,以及该语言与其

他.NET语言之间实现互操作性所需要的完备特征。认识到这点很重要,这里讨论的特征问

题已不仅仅是语言间的简单语法区别。例如,CLS并不去关心一种语言用什么关键字实现继

承,只是关心该语言如何支持继承。

CLS是CTS的一个子集。这就意味着一种语言特征可能符合CTS标准,但又超出CLS的范畴。

例如:C#支持无符号数字类型,该特征能通过CTS的测试,但CLS却仅仅识别符号数字类型。

因此,如果用户在一个组件中使用C#的无符号类型,就可能不能与不使用无符号类型的语

言(如)设计的.NET组件实现互操作。这里用的是“可能不”,而不是“不可能”,因为这

一问题实际依赖于对non-CLS-compliant项的可见性。事实上,CLS规则只适用于或部分适

用于那些与其他组件存在联系的组件中的类型。实际上,用户能够安全实现含私有组件的

项目,而该组件使用了用户所选择使用的.NET语言的全部功能,且无需遵守CLS的规范。另

一方面,如果用户需要.NET语言的互操作性,那么用户的组件中的公共项必须完全符合CLS

规范。让我们来看下面的C#代码:

public class Foo

{

// The uint(unsigned integer)type is non-CLS compliant.

//But since this item is private,the CLS rules do not apply.

7 / 59

文档供参考,可复制、编制,期待您的好评与关注!

private uint A = 4;

// Since shis uint member is public,we have a CLS

// compliance issue.

public uint B = 5;

// The long type is CLS compliant.

public long GetA()

{

return A;

}

}

最后一个C是公共语言运行库Common Language Runtime(CLR)。简单地说,CLR是CTS的实现,

也就是说,CLR是应用程序的执行引擎和功能齐全的类库,该类库严格按照CTS规范实现。

作为程序执行引擎,CLR负责安全地载入和运行用户程序代码,包括对不用对象的垃圾回收

和安全检查。在CLR监控之下运行的代码,称为托管代码(managed code)。作为类库,CLR

提供上百个可用的有用类型,而这些类型可通过继承进行扩展。对于文件I/O、创建对话框、

启动线程等类型—— 基本上能使用Windows API来完成的操作,都可由其完成。

让我们正确看待“3C”。开发人员在构建自己的分布式应用程序时,因为用户在编程时将直接

面对CLR,应将主要精力放在学习了解CLR上,而不是CTS和CLS。而对于希望以.NET平台为

目标的语言和工具开发商来说,就需要深入理解CTS和CLS。互操作性组件是分布式应用的

关键,因此理解.NET如何通过定义公共类型实现这一目标,也就显得十分重要。

4.列举一下你所了解的XML技术及其应用

5.值类型和引用类型的区别?写出C#的样例代码Ref与Out的区别。

Ref与Out的区别是

相同点:

1.使参数按引用传递,注意这里的“引用”与我们通常说的“对象引用”不一样,可以形象的理解为,

类似于C/C++中传指针(地址)。

2.效果是,被调用方对该参数的修改会反映到该变量中,即当调用结束返回时,调用方看到的

是修改过的值。

3.方法定义和调用方法都必须显式使用 ref 或者 out 关键字

不同点:

1。传递到 ref 的参数必须最先初始化,即由调用方显式初始化。

2。传递到 out 的参数在传递之前不需要显式初始化,但需要调用方在方法返回之前必须对其

赋值。

使用场景:

关于重载说明:

1。ref 和 out 关键字在运行时的处理方式不同,但在编译时的处理方式相同。因此,如果一

8 / 59

文档供参考,可复制、编制,期待您的好评与关注!

个方法采用 ref 参数,而另一个方法采用 out 参数,则无法重载这两个方法。

2。但是,如果一个方法采用 ref 或 out 参数,而另一个方法不采用这两类参数,则可以进行

重载。

使用ref前必须对变量赋值,out不用。

out的函数会清空变量,即使变量已经赋值也不行,退出函数时所有out引用的变量都要赋值,

ref引用的可以修改,也可以不修改。

区别可以参看下面的代码:

using System;

class TestApp

{

static void outTest(out int x, out int y)

{//离开这个函数前,必须对x和y赋值,否则会报错。

//y = x;

//上面这行会报错,因为使用了out后,x和y都清空了,需要重新赋值,即使调用函数前赋

过值也不行

x = 1;

y = 2;

}

static void refTest(ref int x, ref int y)

{

x = 1;

y = x;

}

public static void Main()

{

//out test

int a,b;

//out使用前,变量可以不赋值

outTest(out a, out b);

ine("a={0};b={1}",a,b);

int c=11,d=22;

outTest(out c, out d);

ine("c={0};d={1}",c,d);

//ref test

int m,n;

//refTest(ref m, ref n);

//上面这行会出错,ref使用前,变量必须赋值

int o=11,p=22;

9 / 59

文档供参考,可复制、编制,期待您的好评与关注!

refTest(ref o, ref p);

ine("o={0};p={1}",o,p);

}

}

中常用的对象有哪些?分别描述一下。

Connection 对象

Command与DataReader 对象

DataSet 与DataAdapter

7.如何理解委托?

单从委托的概念上来讲,很简单,就是对方法的引用,包括静态方法和对象实例的方法,有点类

似C语言中的方法指针,不过方法指针只能引用静态方法!而且委托是类安全的! 一句话来概

括:委托就是方法的入口!

调用委托就是调用方法,可能有人会说既然调用委托就是调用方法,那为什么不直接调用方

法了,干吗非得通过委托来调用!一开始我也是这么想,包括现在也还有这个疑惑,个人觉得,如

果撇开事件来说,委托除了匿名方法名称之外,没有具体实质型的好处!意思就是说我们如果

不是在事件里用委托,和直接调用方法是没有本质区别的!

至于委托的声明格式,其基本语法为: 修饰符 delegate 返回类型 代理名称(参数列表)

比如说 public delegate void MyDelegate (int i);

实例化的时候给它赋值一个方法(实例或静态方法)名就可以了 MyDelegate MD=new

MyDelegate(类中的方法名)

委托还可以实现多重委托,可以用Combine方法讲不同代理组在一起,也可以用Remove方法

从多重代理中除去一个代理,不过在我们实际使用可以不需要这么麻烦,用+,-可以达到这个

目的!

比如说:

MyDelegate MD=new MyDelegate(方法1);

MyDelegate MD2=new MyDelegate(方法2);

MyDelegate MD3=MD+MD2;

也可以这么写

MyDelegate MD3+=new MyDelegate(方法1);

MyDelegate MD3+=new MyDelegate(方法2);

执行代理MD3就是调用方法1和方法2;

多重代理个人觉得在事件委托中用处很大,因为在实际对象中,一个方法执行会触发多个方

法相继执行,这个时候会需要多重代理这个概念! 使用多重代理的时候要注意方法返回类型

10 / 59

文档供参考,可复制、编制,期待您的好评与关注!

必须是void类型的!

PS:在代理类中有2个属性,一个是Method,表示所应用方法的名称!另一个是Target,表示实

例方法所在对象的类型,如果是静态方法,则返回NULL

事件(Event)

正如我上面说的那样,如果撇开事件,委托好像没有多大用途,但也只是假设,委托就是为事件

服务的,两者是分不开的.言事件比言委托!在C#中,事件和属性,方法一样,是类的一种成员,通

过事件的使用,可以在类的对象发生某种变化,通过事件,来触发某些方法来处理事件的发生!

举个通俗的例子,在的窗体生成种,拖进来一个按钮,双击它,页面后台会自动生成

按钮事件的方法名称,编程人员只要在该方法体内写上具体方法即可! 那么按钮类里面是怎

么实现的了?

具体是这样的,在按钮类里面声明了一个事件委托:

public envet EventHandler Click;

并写了一个触发该事件的方法:

protected virtual void OnClick(EventArges e)

{

if(Click!=Null)

{

Click(this,e)

}

}

而什么时候调用上面这个方法,根据程序结构类型不同而异,在WEB应用程序中,是通过回传

事件接口来调用上面这个方法,在按钮类里只是实现了事件委托,具体双击按钮触发的实际

方法是在页面程序里编写的!(PS:所以这也是我认为使用事件委托的最大好处,机动行好,灵

活,如果不用委托,而是直接调用方法,那么所调用的方法就固定死了,不利于实际面向对象编

程中出现的未预型方法,不灵活了)

在页面程序为按钮绑定事件委托所引用的方法是开发环境自动帮我们完成的,但我们要清楚

实现的必要步骤:

在页面程序里必须给按钮的事件实例化方法,在的页面代码中的private void

InitializeComponent()里要写上:

+= new andler(1_Click);//这里

1_Click指具体执行的方法名称 然后就可以在1_Click方法里写上

具体要执行的代码!

综上所述,实现事件的步骤为:

1.声明事件委托;

2.触发事件的方法;

3.实例化事件委托(给委托添加引用方法)

msdn2005中是这样解释的:

11 / 59

文档供参考,可复制、编制,期待您的好评与关注!

委托具有以下特点:

委托类似于 C++ 函数指针,但它是类型安全的。

委托允许将方法作为参数进行传递。

委托可用于定义回调方法。

委托可以链接在一起;例如,可以对一个事件调用多个方法。

方法不需要与委托签名精确匹配。有关更多信息,请参见协变和逆变。

C# 2.0 版引入了匿名方法的概念,此类方法允许将代码块作为参数传递,以代替单独定义

的方法。

委托适用于那种在某些其他语言中需用函数指针来解决的情况(场合)。但是,与函数指针不

同,委托是面向对象和类型安全的。

委托声明定义一个类,它是从 te 类派生的类。委托实例封装了一个调用

列表,该列表列出了一个或多个方法,每个方法称为一个可调用实体。对于实例方法,可调用

实体由一个实例和该实例的方法组成。对于静态方法,可调用实体仅由一个方法组成。如果用

一组合适的参数来调用一个委托实例,则该委托实例所封装的每个可调用实体都会被调用,并

且用的都是上述的同一组参数。

委托实例的一个有趣且有用的属性是:它既不知道也不关心有关它所封装的方法所属的类的

种种详情;对它来说最重要的是这些方法与该委托的类型兼容(第 15.1 节)。这使委托

非常适合“匿名”调用。这是一个强大的功能。

定义和使用委托分三个步骤:声明、实例化和调用。

8.C#中的接口和类有什么异同。

一个接口定义一个协定。实现接口的类或结构必须遵守其协定。接口可以包含方法、属性、

索引器和事件作为成员。

接口是负责功能的定义,项目中通过接口来规范类,操作类以及抽象类的概念!

而类是负责功能的具体实现!

在类中也有抽象类的定义,抽象类与接口的区别在于:

抽象类是一个不完全的类,类里面有抽象的方法,属性,也可以有具体的方法和属性,需要进

一步的专业化。

但接口是一个行为的规范,里面的所有东西都是抽象的!

一个类只可以继承一个基类也就是父类,但可以实现多个接口

PS:接口除了规范一个行为之外,在具体项目中的实际作用也是十分重要的,在面向对象的设

计原则以及设计模式的使用中,无不体现作为一个接口的使用好处,最直接的就是设计原则中

OCP(开放封闭原则),我们使用接口,而不需要关心他的具体实现,具体实现的细节变化也无

关客户端(使用接口的类)的使用,对与扩展是开放的,我们可以另写一个接口的实现来扩展

当前程序,而不影响上层的使用,但对修改是封闭的,即我们不能够再去修改接口的定义,当

然这个“不能够”是指在规范原则上不应该这么做!

12 / 59

文档供参考,可复制、编制,期待您的好评与关注!

9.。net中读写数据库需要用到哪些类?他们的作用

连接和TCP连接的异同。

的身份验证方式有哪些?分别是什么原理?

12.进程和线程分别怎么理解?

简单的说,你每启动一个程序,就启动了一个进程。在Windows 3.x下,进程是最小运行

单位。在Windows 95/NT下,每个进程还可以启动几个线程,比如每下载一个文件可以单

独开一个线程。在Windows 95/NT下,线程是最小单位。WINDOWS的多任务特性使得线程之

间独立运行,但是它们彼此共享虚拟空间,也就是共用变量,线程有可能会同时操作一片

内存。 线程与进程的区别多线程共存于应用程序中是现代操作系统中的基本特征和重要标

志。用过UNIX操作系统的读者知道进程,在UNIX操作系统中,每个应用程序的执行都在

操作系统内核中登记一个进程标志,操作系统根据分配的标志对应用程序的执行进行调度

和系统资源分配,但进程和线程有什么区别呢?进程和线程都是由操作系统所体会的程序

运行的基本单元,系统利用该基本单元实现系统对应用的并发性。进程和线程的区别在于:

线程的划分尺度小于进程,使得多线程程序的并发性搞。另外,进程在执行过程中拥有独

立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。线程在执行过

程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序

的出口

13.什么是code-Behind技术。

14.活动目录的作用。

15..net中读写XML的类都归属于哪些命名空间?

16.解释一下UDDI、WSDL的意义及其作用。

17.什么是SOAP,有哪些应用。

答:SOAP(Simple Object Access Protocol )简单对象访问协议是在分散或分布式的环境中交

换信息并执行远程过程调用的协议,是一个基于XML的协议。使用SOAP,不用考虑任何特

定的传输协议(最常用的还是HTTP协议),可以允许任何类型的对象或代码,在任何平台

上,以任何一直语言相互通信。这种相互通信采用的是XML格式的消息,具体请

看:/

18.如何部署一个页面。

13 / 59

文档供参考,可复制、编制,期待您的好评与关注!

19.如何理解.net中的垃圾回收机制。

20.常用的调用webservice方法有哪些?

l与abstraction区别?

22.结构与类有何差异?哪些时候比较适合使用结构和类?

它们的相同之处:

1,两者都是Container类型,这表示它们可以包含其他数据类型作为成员.

2,两者都拥有成员,这些成员包括:构造函数,方法,属性,字段,常量,枚举类型,事件,以及

事件处理函数.

3,两者的成员都有其各自的存取范围.例如,您可以将某一个成员声明为Public,而将另外

一人成员声明为Private

4,两者都可以实现接口.

5,两者都可以公开一个默认属性,然而前提是这个属性至少要取得一个自变量.

6,两者都可以声明和触发事件,而且两者都可以声明委托(Delegate).

7,结构与类都可以完全是空的.

它们的不同之处如下:

1,结构是实值类型(Value Types),而类是引用类型(Reference Types).

2,结构使用载存储(Stack Allocation),而类使用堆存储(Heap Allocation).

3,所有结构成员默认都是Public, 而类的变量与常量数则默认为(Private,不过其他类成

员默认都是Public.

4,结构成员国不能被声明为Protected,但是类成员可以这样做.

5,结构变量声明不能指定初始值,使用new关键字词或对数组进行初始化,但类变量声明则

可以这样做.

6,结构不能声明默认的构造函数,也就是不拥有参数的非共享构造函数,但是类则无此限

制.

7,二者都可以拥有共享构造函数,结构的共享构造函数不能带有参数,但类的共享构造函数

则可以带或者不带参数.

8,结构不允许声明析构函数(Destructor),类则无此限制.

9,结构的实例(Instance)声明,不允许对包含的变量进行初始化设定,类则可以在声明类的

实例时,同时进行变量初始化.

10,结构是隐式继承自ValueType类而且不能继承任何其它的类型,类则可以继承来自

ValueType以外的任何类.

11,结构是无法被继承的,类则可以被继承.

14 / 59

文档供参考,可复制、编制,期待您的好评与关注!

12,结构永远不会终止,因此 Common Language Runtime(CLR)不会在任何结构上调用

Finalize方法.类则是由内存回收进程加以终止,当内存回收进程检测到没有任何作用的

类时,它就会调用类的Finalize方法.

13,结构不需要构造函数,类则需要构造函数.

14,结构只能在一种情况下使用非共享构造函数,那就是非共享构造函数会接收参数:但是

类则无此限制,它可以使用带参数或不带参数的非共享构造函数.

15,每一个结构都具有无参数的隐含公共构造函数.此构造函数会将结构的所有成员初始化

为基默认值.您不能重新定义这个行为.

除了上述的相似处与相异点之外,我们还可以在”实例与变量”层面上来探讨结构与类.由

于结构是数值类型的,因此每个结构变量会永久地绑定到结构实例上.然而类是引用类型

的,而且对象变量可引用不同的类实例.在此方面的区别,会对于使用结构与类造成下列

影响:

1结构变量会隐式地使用结构的无参数构造函数来初始化成员,这就意味着,语句Structl S

就等于Structl S=new Structl();

2当您好将一个结构变量赋值给另一个,或是将结构实例传递到程序变量时,所有变量成员

的值会复制到新的结构中.当您将一个对象变量赋值给另一个,或是将对象变量传递到程

序时,则只会复制指针.

3,您可以将Null值赋值给结构变量,但是该实例会一直与该变量保持关联.虽然变量成员会

因此赋值而重新初始化,但是您还是可以调用变量的方法并访问其数据成员.相反地,如

果您将对象变量设定为Null,您就会中断它与任何类实例的关联,而且除非您再将另外一

个实例赋值给它,否则无法通过变量访问任何成员.

4,您可以在不同时间将不同的类的实例赋值给同一个对象变量,而且在同一时间可以有好

几个对象变量引用相同的类实例,如果您对类成员值做了改变,则其它指向相同实例的对

象变量也会发生改变.然而,结构成员则会封装在它们自己的实例中,变更结构成员值并

不会对其它任何结构变量的成员造成影响,甚至也不会影响相同Struct声明的其它实例.

5,两个结构必须以成员对成员的比较方式来执行相等比较.两个对象变量可以使用Equals

方法来加以比较.Equals会判断两个变量是否指向相同的实例.

在下列状况中,比较适合使用结构

1,您拥有少量数据而且希望使用会传递的方式来为变量赋值时.

2您会在每一个实例上执行大量的操作,而且若使用堆来管理会造成性能下降.

3,您不需要进行继承,而且不需要实例有特殊性.

4,您不会采用Boxing与Unboxing结构.

5,您会在Managed与UnManaged程序代码之间传递Blittable数据.

在下列情况中,比较适合使用类:

1,您需要使用继承与多态.

2,您需要在创建阶段初始化一个或多个成员.

3,您需要提供一个非参数型的构造函数.

4,您需要没有任何限制的事件处理支持.

15 / 59

文档供参考,可复制、编制,期待您的好评与关注!

23.谈谈你对二维树的理解?

24

.如何把一个array复制到arrayList里

foreach( object o in array )(o);

25

.use可以连接什么数据源 [dataset,datatable,dataview]

dataset,datatable,dataview , IList

26

.概述反射和序列化

反射:程序集包含模块,而模块包含类型,类型又包含成员。反射则提供了封装

程序集、模块和类型的对象。您可以使用反射动态地创建类型的实例,将类型

绑定到现有对象,或从现有对象中获取类型。然后,可以调用类型的方法或访

问其字段和属性

序列化:序列化是将对象转换为容易传输的格式的过程。例如,可以序列化一个

对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象。在

另一端,反序列化将从该流重新构造对象。

27

.概述o/r mapping 的原理

利用反射,配置 将类于数据库表映射

28

.类成员有( )种可访问形式

可访问形式?不懂。

可访问性:public ,protected ,private,internal

29

.用sealed修饰的类有什么特点

sealed 修饰符用于防止从所修饰的类派生出其它类。如果一个密封类被指定为

其他类的基类,则会发生编译时错误。

密封类不能同时为抽象类。

sealed 修饰符主要用于防止非有意的派生,但是它还能促使某些运行时优化。

具体说来,由于密封类永远不会有任何派生类,所以对密封类的实例的虚拟函

数成员的调用可以转换为非虚拟调用来处理。

30.C#中,string str = null 与 string str ="",请尽量用文字说明区别。(要点:说明详细

的内存空间分配)

31.概述三层结构体系

16 / 59

文档供参考,可复制、编制,期待您的好评与关注!

如何实现MVC模式,举例说明!

33.。net中读写数据库需要用到哪些类?他们的作用

的身份验证方式有哪些?分别是什么原理?

35.

.net Remoting与webservices区别?

36

.C#可否对内存进行直接的操作

37:您在什么情况下会用到虚方法?它与接口有什么不同?

38:Override与重载有什么区别?

39:值类型与引用类型有什么区别?

40:怎样理解静态变量?

41:向服务器发送请求有几种方式?

42:DataReader与DataSet有什么区别?

43:如果在一个B/S结构的系统中需要传递变量值,但是又不能使用Session、Cookie、

Application,您有几种方法进行处理?

使用er

这个方法相比上面介绍的方法稍微复杂一点,但在页面间值传递中却是特别有用的,使用

该方法你可以在另一个页面以对象属性的方式来存取显露的值,当然了,使用这种方法,你需

要额外写一些代码以创建一些属性以便可以在另一个页面访问它,但是,这个方式带来的好处

也是显而易见的。总体来说,使用这种方法是简洁的同时又是面向对象的。使用这种方法的整

17 / 59

文档供参考,可复制、编制,期待您的好评与关注!

个过程如下:

1,在页面里添加必要的控件

2,创建返回值的Get属性过程

3,创建可以返回表单的按钮和链接按钮

4,在按钮单击事件处理程序中调用er方法转移到指定的页面

5,在第二个页面中,我们就可以使用r属性来获得前一个页面实例对象的

引用,通过它,就可以使用存取前一个页面的控件的值了

以下代码综合实现上述步骤过程的代码:

源页面代码:

把以下的代码添加到页面中

public string Name

{

get

{

return ;

}

}

public string EMail

{

get

{

return ;

}

}

然后调用er方法

private void Button1_Click

(object sender, rgs e)

{

er("";

}

目标页面代码:

private void Page_Load

(object sender, rgs e)

{

//create instance of source web form

WebForm1 wf1;

//get reference to current handler instance

wf1=(WebForm1)r;

18 / 59

文档供参考,可复制、编制,期待您的好评与关注!

=;

=;

}

在 2.0中启用了跨页面传送功能,其功能和用法在以后在做介绍!

页面之间传递值

方式1:

在接收页 的html代码里加上一行: <%@ Reference Page = "" %>

WebForm1 fp=(WebForm1)r;

=; //name 是第一页的public变量

Context 提供对整个当前上下文(包括请求对象)的访问。您可以使用此类共享页之间的

信息。

方式2:GET方式

在发送页

public int sum=0;

int i =()*2;

er("?sum="+i);

接收页

=Request["sum"].ToString();

or =["sum"].ToString();

=tring["sum"];

方法3:全局变量

发送页:

Application["sum"]=;

er("";

接收页:

=(string)Application["sum"];

Application实质上是整个虚拟目录中所有文件的集合,如果想在整个应用范围内使用某个

变量值,Application对象将是最佳的选择

在这里用Session[""]的方法雷同

方法4:

发送页:

1.定义静态变量: public static string str="";

2. str=;

er("";

接收页:

1.引入第一页的命名空间:using WebApplication1;

2 =;

19 / 59

文档供参考,可复制、编制,期待您的好评与关注!

44:软件开发过程一般有几个阶段?每个阶段的作用?

45:微软推出了一系列的Application Block,请举出您所知道的Application Block并说

明其作用?

46:请列举一些您用到过的设计模式以及在什么情况下使用该模式?

47:您对WebService的体会?

以下几道题目如果您不会,请较为详细的描述您的解决思路和方法

48:通过超链接怎样传递中文参数?

49:请编程遍历页面上所有TextBox控件并给它赋值为?

50:请编程实现一个冒泡排序算法?

51.下面这段代码输出什么?为什么?

int i=5;

int j=5;

if (nceEquals(i,j))

ine("Equal");

else

ine("Not Equal");

52.对于这样的一个枚举类型:

enum Color:byte{

Red,

Green,

Blue,

Orange

}

string[] ss=es(typeof(Color));

byte[] bb=ues(typeof(Color));

试写一段程序显示出枚举类型中定义的所有符号名称以及它们对应的数值。

20 / 59

文档供参考,可复制、编制,期待您的好评与关注!

53.一个长度为10000的字符串,通过随机从a-z中抽取10000个字符组成。请用c#语

言编写主要程序来实现。

54.在c#中using和new这两个关键字有什么意义,请写出你所知道的意义?using 指

令 和语句 new 创建实例 new 隐藏基类中方法

55

下面这段代码有错误么?

switch (i){

case():

CaseZero();

break;

case 1:

CaseOne();

break;

case 2:

dufault; //wrong

CaseTwo();

break;

}

56

当类T只声明了私有实例构造函数时,则在T的程序文本外部,___可以___(可以 or 不可

以)从T派生出新的类,不可以____(可以 or 不可以)直接创建T的任何实例。

12.下面的代码中有什么错误吗?_______

using System;

class A

{

public virtual void F(){

ine("A.F");

21 / 59

文档供参考,可复制、编制,期待您的好评与关注!

}

}

abstract class B:A

{

public abstract override void F(); // new public abstract void F();

}

1.c#中的三元运算符是__?:___?

2.当整数a赋值给一个object对象时,整数a将会被__装箱(封装)___?

3.类成员有_____种可访问形式? this.;new Class().Method;

static const int A=1;这段代码有错误么?是什么? const不能用static修饰

f=-123.567F;

int i=(int)f;

i的值现在是_____? 123

6.利用operator声明且仅声明了“==”,有什么错误么?

7.委托声明的关键字是______? delagete

8.用sealed修饰的类有什么特点?密封,不能继承

9.在中所有的自定义用户控件都必须继承自________?Control

10.在.Net中所有可序列化的类都被标记为_____?

11.在.Net托管代码中我们不用担心内存漏洞,这是因为有了______?gc

1.有哪几种方法可以实现一个类存取另外一个类的成员函数及属性,并请举列来加以说明和分

析.

2.如果需记录类的实例个数,该如何实现,请写一个简单的类于以证明.

3.A类是B类的基类,并且都有自己的构造,析构函数,请举例证明B类从实例化到消亡过程中构造,

析构函数的执行过程.

4.需要实现对一个字符串的处理,首先将该字符串首尾的空格去掉,如果字符串中间还有连续空

格的话,仅保留一个空格,即允许字符串中间有多个空格,但连续的空格数不可超过一个.

2、.net的错误处理机制是什么

数据库方面:

1.存储过程和函数的区别

22 / 59

文档供参考,可复制、编制,期待您的好评与关注!

2.事务是什么?

3.游标的作用?如何知道游标已经到了最后?

4.触发器分为事前触发和事后触发,这两种触发有和区别。语句级触发和行级触发有何区别。

1。用C#实现以下功能

a 产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。

int[] intArr=new int[100];

ArrayList myList=new ArrayList();

Random rnd=new Random();

while(<100)

{

int num=(1,101);

if(!ns(num))

(num);

}

for(int i=0;i<100;i++)

intArr[i]=(int)myList[i];

b 对上面生成的数组排序,需要支持升序、降序两种顺序

2。请说明在.net中常用的几种页面间传递参数的方法,并说出他们的优缺点。

session(viewstate) 简单,但易丢失

application 全局

cookie 简单,但可能不支持,可能被伪造

input ttype="hidden" 简单,可能被伪造

url参数 简单,显示于地址栏,长度有限

数据库 稳定,安全,但性能相对弱

3。请说明.net中的错误处理机制,并举例

try catch final

4。请说出强名的含义

具有自己的key,可以在GAC(全局程序集缓存)为公用

5。请列出c#中几种循环的方法,并指出他们的不同

for wile foreach

23 / 59

文档供参考,可复制、编制,期待您的好评与关注!

6。请指出.net中所有类型的基类

object

7。请指出GAC的含义

8。SQL SREVER中,向一个表中插入了新数据,如何快捷的得到自增量字段的当前值

试卷

1. 填空: (1)面向对象的语言具有________性、_________性、________性。

(2)能用foreach遍历访问的对象需要实现 ________________接口或声明

________________方法的类型。

(3)列举中的五个主要对象_______________、_____________、

_______________、_______________、_________________。

Connection,Command,DataReader,DataAdapter,DataSet

connection 连接对象

command 命令对象,指示要执行的命令和存储过程!

datareader是一个向前的只读的数据流。

dataadapter是功能强大的适陪器,支持增删改查的功能

dataset是一个数据级对象,相当与内存中的一张表或多张表!

2. 不定项选择:

(1) 以下叙述正确的是:

A. 接口中可以有虚方法。 B. 一个类可以实现多个接口。

C. 接口不能被实例化。 D. 接口中可以包含已实现的方法。

(2) 从数据库读取记录,你可能用到的方法有:

A. ExecuteNonQuery B. ExecuteScalar

C. Fill D. ExecuteReader

3. 简述 private、 protected、 public、 internal 修饰符的访问权限。

4. 写出一条Sql语句: 取出表A中第31到第40记录(SQLServer, 以自动增长的ID作为主键,

意:ID可能不是连续的。)

5 .列举 页面之间传递值的几种方式。

6. 写出程序的输出结果

class Class1 {

private string str = "";

private int i = 0;

static void StringConvert(string str) {

str = "string being converted.";

}

static void StringConvert(Class1 c) {

= "string being converted.";

}

24 / 59

文档供参考,可复制、编制,期待您的好评与关注!

static void Add(int i) {

i++;

}

static void AddWithRef(ref int i) {

i++;

}

static void Main() {

int i1 = 10;

int i2 = 20;

string str = "str";

Class1 c = new Class1();

Add(i1);

AddWithRef(ref i2);

Add(c.i);

StringConvert(str);

StringConvert(c);

ine(i1);

ine(i2);

ine(c.i);

ine(str);

ine();

}

}

7.写出程序的输出结果

public abstract class A

{

public A()

{

ine('A');

}

public virtual void Fun()

{

ine("()");

}

}

public class B: A

{

25 / 59

文档供参考,可复制、编制,期待您的好评与关注!

public B()

{

ine('B');

}

public new void Fun()

{

ine("()");

}

public static void Main()

{

A a = new B();

();

}

}

8. 写出程序的输出结果:

public class A

{

public virtual void Fun1(int i)

{

ine(i);

}

public void Fun2(A a)

{

1(1);

Fun1(5);

}

}

public class B : A

{

public override void Fun1(int i)

{

1 (i + 1);

}

public static void Main()

{

B b = new B();

A a = new A();

2(b);

26 / 59

文档供参考,可复制、编制,期待您的好评与关注!

2(a);

}

}

9. 一列数的规则如下: 1、1、2、3、5、8、13、21、34......

求第30位数是多少, 用递归算法实现。(C#语言)

10. 程序设计: 猫大叫一声,所有的老鼠都开始逃跑,主人被惊醒。(C#语言)

要求: 1.要有联动性,老鼠和主人的行为是被动的。

2.考虑可扩展性,猫的叫声可能引起其他联动效应。

参考答案:

1. (1) 继承性、封装性、多态性。(考基本概念)

(2) IEnumerable 、 GetEnumerator (对foreach机制的理解,本来不想出这题的,凑分)

(3) ... (送分题, 对的了解)

评分标准:一空1分,满分10分。

2. (1) B、C (考对接口的理解) (2) B、C、D (考查对的熟练程度)

评分标准: 一题5分,不选或者错选均不得分。漏选得2分。满分10分。

3. . private : 私有成员, 在类的内部才可以访问。

protected : 保护成员,该类内部和继承类中可以访问。

public : 公共成员,完全公开,没有访问限制。

internal: 在同一命名空间内可以访问。

评分标准:答对1题2分,2题5分,3题7分。全对10分。 (送分题)

4. 解1: select top 10 * from A where id not in (select top 30 id from A)

解2: select top 10 * from A where id > (select max(id) from (select top 30 id from

A )as A)

评分标准: 写对即10分。(答案不唯一,datagrid 分页可能需要用到)

5. 1.使用QueryString, 如....?id=1; response. Redirect()....

2.使用Session变量

3.使用er

....等等

评分标准: 答对1点得3分, 两点7分, 3点10分。

6. (考查值引用和对象引用)

10

21

0

str

string being converted.

评分标准:答对一点得2分,满分10分。

27 / 59

文档供参考,可复制、编制,期待您的好评与关注!

7. A

B

()

评分标准: 写出A.B 得5分,写出()得5分,满分10分。

(考查在继承类中构造函数, 以及new 方法, )

8. 2

5

1

6

评分标准: 答对一点得2分,两点得5分,3点得7分。全对得10分。

(一些人做这题,头都晕了.... ^_^ )

9.

public class MainClass

{

public static void Main()

{

ine(Foo(30));

}

public static int Foo(int i)

{

if (i <= 0)

return 0;

else if(i > 0 && i <= 2)

return 1;

else return Foo(i -1) + Foo(i - 2);

}

}

评分标准: 写出return Foo(i -1) + Foo(i - 2); 得5分。

28 / 59

文档供参考,可复制、编制,期待您的好评与关注!

写出if(i > 0 && i <= 2) return 1; 得5分。

方法参数过多需要扣分(扣除分数 = 参数个数 - 1)

不用递归算法扣5分

(递归算法在树结构建立等方面比较常用)

10

要点:1. 联动效果,运行代码只要执行()方法。2. 对老鼠和主人进行抽象

评分标准: <1>.构造出Cat、Mouse、Master三个类,并能使程序运行(2分)

<2>从Mouse和Master中提取抽象(5分)

<3>联动效应,只要执行()就可以使老鼠逃跑,主人惊醒。(3分)

public interface Observer

{

void Response(); //观察者的响应,如是老鼠见到猫的反映

}

public interface Subject

{

void AimAt(Observer obs); //针对哪些观察者,这里指猫的要扑捉的对象---老鼠

}

public class Mouse : Observer

{

private string name;

public Mouse(string name, Subject subj)

{

= name;

(this);

}

public void Response()

{

ine(name + " attempt to escape!");

29 / 59

文档供参考,可复制、编制,期待您的好评与关注!

}

}

public class Master : Observer

{

public Master(Subject subj)

{

(this);

}

public void Response()

{

ine("Host waken!");

}

}

public class Cat : Subject

{

private ArrayList observers;

public Cat()

{

ers = new ArrayList();

}

public void AimAt(Observer obs)

{

(obs);

}

public void Cry()

{

ine("Cat cryed!");

foreach (Observer obs in ers)

{

se();

}

}

}

class MainClass

{

static void Main(string[] args)

30 / 59