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

private :设置类或类的成员为私有,在类的内部才可以访问。有时要访问私有成员时,可通过get和set属性访问器读取或者修改。

protected :保护成员,该类内部和继承类(子类)中可以访问。(即使子类和基类不在同一个程序集中)

public : 公共成员,完全公开,没有访问限制。须谨慎使用,滥用会影响类的封装性。

internal:  在同一命名空间(程序集)内可以访问。C#默认的类访问修饰符即为internal。(默认的修饰符,可缺省,最常用)

2. 描述sealed修饰符的作用

用于修饰类、实例方法和属性。sealed修饰类时,该类无法被继承,所以该类也被称为密封类。而abstract类(抽象类)必须被继承才有意义,所以二者是相互排斥,无法共用的。密封方法会重写基类的方法,sealed用于修饰实例被重写的虚方法或虚属性时,表示该方法或属性无法再被重写。

3、举例说明简单工厂模式的作用

在软件系统中,经常面临“一系列相互依赖对象”的创建工作,为了绕过常规对象的创建方式(即用new创建),利用工厂模式,提供一种“封装机制”来减少功能调用程序和“多系列具体对象创建工作”的耦合性。

简单工厂模式,在工厂类中封装创建对象的实现部分。在应用接口的程序中广泛应用。如下例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace BaseFactory
{
//声明一个图书接口
interface IBook
{
//声明未实现的图书类型方法bookType()
void bookType();
}
//实现图书接口的A类图书
class BookA : IBook
{
public void bookType()
{
Console.WriteLine("A类书籍");
}
}
//实现图书接口的B类图书
class BookB : IBook
{
public void bookType()
{
Console.WriteLine("B类书籍");
}
}
//实例化各类图书对象的工厂
class PublishFactory
{
private IBook bka = new BookA(); //封装创建对象的实部分
private IBook bkb = new BookB();
public IBook getBook(int i)
{
switch (i)
{
case 1:
return bka;
case 2:
return bkb;
default:
return bka;
}
}
}
public class BasicFactory
{
static void Main(string[] args)
{
PublishFactory pf = new PublishFactory();
Console.Write("请输入编号(1或2):");
int i = int.Parse(Console.ReadLine());
//根据输入的不同参数获得不同的图书对象
IBook obj = pf.getBook(i);
obj.bookType();
}
} }

接口反映了面向对象编程的一个特性,即多态,多态即通过相同的方法得到不同的实现。如上面的h1.getFav()和h2.getFav();

接口反映了面向对象编程的另个特性,即封装,使用者可以不清楚接口成员实现的细节。

解释: 接口类型obj可以引用不同类的实例,以致相同的bookType方法有不同的表现;使用者只知道传递数字来使用不同接口的不同功能,对内部实现一无所知。实现了更好的封装。

(此例已经够说明了)

运行结果:

为了处理更复杂的情况,可以将产品再次细分为多个类,用抽象类进行归纳,完成同类产品中共用代码的复用,工厂类也相应地分为多个类,用抽象类进行归纳。如下例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace LxFactory
{
//声明一个人类接口
interface Ihuman
{
void getFav(); //声明未实现的爱好方法getFav()
string getStatus(); //声明未实现的身份状态(孩子,成年人)方法
} //声明一个抽象类Children,并实现接口的部分方法
abstract class Children : Ihuman
{
protected string _status = "孩子";
//实现接口Ihuman中的getStatus()方法
public string getStatus()
{
return _status;
}
//将接口Ihuman中的getFav()方法映射到抽象方法
abstract public void getFav();
}
//声明一个抽象类Adult,并实现接口的部分方法
abstract class Adult : Ihuman
{
protected string _status = "成年人";
//实现接口Ihuman中的getStatus()方法
public string getStatus()
{
return _status;
}
//将接口Ihuman中的getFav()方法映射到抽象方法
abstract public void getFav();
} //声明男孩类Boy,继承小孩类Children,重写爱好方法getFav()
class Boy : Children
{
public override void getFav()
{
Console.WriteLine("男孩,我喜欢游戏!");
}
}
//声明女孩类Girl,继承小孩类Children,重写爱好方法getFav()
class Girl : Children
{
public override void getFav()
{
Console.WriteLine("女孩,我喜欢布娃娃!");
}
}
//声明男人类Man,继承成人类Adult,重写爱好方法getFav()
class Man : Adult
{
public override void getFav()
{
Console.WriteLine("男人,我喜欢编程!");
}
}
//声明女人类Woman,继承成人类Adult,重写爱好方法getFav()
class Woman : Adult
{
public override void getFav()
{
Console.WriteLine("女人,我喜欢逛街!");
}
} //声明一个抽象工厂,分别创建相应类的实例
abstract class HumanFactory
{
protected Ihuman h1 = new Boy();
protected Ihuman h2 = new Man();
protected Ihuman h3 = new Girl();
protected Ihuman h4 = new Woman(); //创建一个方法,根据不同输入返回一个接口的引用
abstract public Ihuman getHuman(int i);
}
//声明可以实例化各种类的工厂Factory1,继承类HumanFactory,重写抽象方法getHuman()
class Factory1 : HumanFactory
{
//根据不同输入获得不同对象所属接口的引用
public override Ihuman getHuman(int i)
{
switch (i)
{
case 1:
return h1;
case 2:
return h2;
default:
return h1;
}
}
}
//声明可以实例化各种类的工厂Factory1,继承类HumanFactory,重写抽象方法getHuman()
class Factory2 : HumanFactory
{
//根据不同输入获得不同对象所属接口的引用
public override Ihuman getHuman(int i)
{
switch (i)
{
case 1:
return h3;
case 2:
return h4;
default:
return h3;
}
}
}
public class LxFactory
{
static void Main(string[] args)
{
//使用工厂1
Console.WriteLine("男性中有两种人,请选择编号【1】男孩【2】男人:");
int input1 = Int32.Parse(Console.ReadLine());
Factory1 f1 = new Factory1();
Ihuman h1 = f1.getHuman(input1);
h1.getFav();
Console.WriteLine("我的身份是:{0}", h1.getStatus()); //使用工厂2
Console.WriteLine("女性中有两种人,请选择编号【1】女孩【2】女人:");
int input2 = Int32.Parse(Console.ReadLine());
Factory2 f2 = new Factory2();
Ihuman h2 = f2.getHuman(input2);
h2.getFav();
Console.WriteLine("我的身份是:{0}", h2.getStatus());
}
} }

运行结果:

4、访问关键字this和base有什么作用

this用于引用类的当前实例(this仅限于构造函数和方法成员中使用,静态成员与实例无关,所以静态成员中不能用this)

base用于派生类访问基类成员(基类被重写的方法和基类的构造函数)

5、简述程序集和应用程序域

程序集

一个.NET应用程序可以由多个程序集拼装而成的。程序集,简单来说,就是一个以公共语言运行库(CLR)为宿主的、版本化的、自描述的二进制文件。尽管显示中.NET程序集和以往Win32二进制文件(包括遗留的COM服务对象)的文件扩展名(*.exe或*.dll)完全相同,但是两者的内部构成几乎完全不同。

程序集可以促进代码重用、确定类型边界、可版本化的单元、自描述的、可配置的。

n CIL代码

程序集的核心部分包含CIL代码,这些CIL代码是独立于平台和CPU的中间语言。运行时,程序集内部的CIL代码才被编译成特定平台和CPU的指令。

n 类型元数据

元数据完整的描述了程序集内含另行和引用外部类型的格式。

n 程序集清单

详细记录了程序集中的每一个模块,构建程序集的版本以及该程序集引用的所有外部程序集。

n 可选的嵌入资源

NET平台下,程序集并没有直接加载进进程中(传统的Win32程序是直接承载的)。.NET可执行程序(程序集)承载在进程的一个逻辑分区中,术语称应用程序域(简称AppDomain)。一个进程可以拥有多个应用程序域,应用程序域的全部目的就是提供隔离性,相比较与传统的:(代码, AppDomain.currentDomain)

1.应用程序域是.NET平台操作系统独立性的关键特性。这种逻辑分区将不同操作系统表现加载可执行程序的差异抽象化了。

2.和一个完整的进程相比,应用程序域的CPU和内存占用要小的多。

3.应用程序域为承载的应用程序提供了深度的隔离。一个失败,其他不会失败。

单个进程可以承载多个应用程序域,每个程序域都和该进程的其他程序域隔离开来,无法相互访问。在线程启动的时候,CLR将自动创建这个特定的应用程序域(默认应用程序域)。然后根据需要创建其他程序域。

 

两边都有mscorlib.dll(程序集),因为所有关键程序集会被CLR自动加载到每一个应用程序域中。

6、简述结构和类的区别

答:(1)结构是值类型(传递的是数据的副本),类是引用类型。所以结构的实例化可以不用new运算符。

(值类型变量一旦超出作用域即被销毁,而应用类型由内存垃圾处理机制完成收集)

(2)结构不能声明无参数的构造函数(默认构造函数)和析构函数。类可以同时有构造函数和析构函数。

(3)结构不支持继承,也无法派生其他的结构或类,(但结构可以实现接口)。而类支持继承。

7、C#函数的参数 修饰符(out、params、ref)的作用

(1)无修饰符,表示按值传递

(2)out修饰,eg. 函数 static void equal(out int a,out int b,out int c)

{ a=2; b=a*100; c=b*100; Console.WriteLine("a、b、c的值分别为:{0}、{1}、{2}",a,b,c);}

表示按引用 传递参数,实际参数(调用的函数里的参数)传递前不需要赋初值,函数(定义的函数)必须将其赋值。也可以看出out能用于一次调用返回多个值

(3)params修饰,表示形式参数 可以为不确定个数的一组实际参数,这些实际参数必须具有相同的数据类型。

void text(params string[] txt){}

(4)ref修饰,类似out参数。也表示按引用 传递参数,不过实际参数传递前需要赋初值。

8、如何使用C#的对象构造器

这是一种新的构造并初始化对象的方法,使用时只需将初始化成员的语句用逗号分隔,位置紧跟在构造函数后面。

eg. Snake a=new Snake("眼镜蛇"){nm="蟒蛇",Len=10,Wei=20 };

后面大括号就是对象构造器。。列出了 对象a 的初始化值。  这种方式非常灵活的初始化对象成员,无需定义过多的重载构造函数。

9、如何判断类型实现了某个接口  (as/is关键词)

ClassA a=new ClassA();

var msg=a as ITest;

class  ClassA:ITest{ 类体}

if(msg==null)

{"未实现"}

else {"实现了"}

或者用 a is ITest

10、数组列表和数组有什么区别

非常相似,但是数组列表(即ArrayList类, 位于System.Collection下)的容量可以动态变化;有点类似StringBuilder类。。

ArrayList.Add(); ArrayList.Insert(); ArrayList.AddRange();-----

数组(即Array类,位于System下,)在初始化时要指定容量,并且指定后无法更改。

《.NET程序员面试秘籍》读书笔记的更多相关文章

  1. csapp读书笔记-并发编程

    这是基础,理解不能有偏差 如果线程/进程的逻辑控制流在时间上重叠,那么就是并发的.我们可以将并发看成是一种os内核用来运行多个应用程序的实例,但是并发不仅在内核,在应用程序中的角色也很重要. 在应用级 ...

  2. CSAPP 读书笔记 - 2.31练习题

    根据等式(2-14) 假如w = 4 数值范围在-8 ~ 7之间 2^w = 16 x = 5, y = 4的情况下面 x + y = 9 >=2 ^(w-1)  属于第一种情况 sum = x ...

  3. CSAPP读书笔记--第八章 异常控制流

    第八章 异常控制流 2017-11-14 概述 控制转移序列叫做控制流.目前为止,我们学过两种改变控制流的方式: 1)跳转和分支: 2)调用和返回. 但是上面的方法只能控制程序本身,发生以下系统状态的 ...

  4. CSAPP 并发编程读书笔记

    CSAPP 并发编程笔记 并发和并行 并发:Concurrency,只要时间上重叠就算并发,可以是单处理器交替处理 并行:Parallel,属于并发的一种特殊情况(真子集),多核/多 CPU 同时处理 ...

  5. 读书笔记汇总 - SQL必知必会(第4版)

    本系列记录并分享学习SQL的过程,主要内容为SQL的基础概念及练习过程. 书目信息 中文名:<SQL必知必会(第4版)> 英文名:<Sams Teach Yourself SQL i ...

  6. 读书笔记--SQL必知必会18--视图

    读书笔记--SQL必知必会18--视图 18.1 视图 视图是虚拟的表,只包含使用时动态检索数据的查询. 也就是说作为视图,它不包含任何列和数据,包含的是一个查询. 18.1.1 为什么使用视图 重用 ...

  7. 《C#本质论》读书笔记(18)多线程处理

    .NET Framework 4.0 看(本质论第3版) .NET Framework 4.5 看(本质论第4版) .NET 4.0为多线程引入了两组新API:TPL(Task Parallel Li ...

  8. C#温故知新:《C#图解教程》读书笔记系列

    一.此书到底何方神圣? 本书是广受赞誉C#图解教程的最新版本.作者在本书中创造了一种全新的可视化叙述方式,以图文并茂的形式.朴实简洁的文字,并辅之以大量表格和代码示例,全面.直观地阐述了C#语言的各种 ...

  9. C#刨根究底:《你必须知道的.NET》读书笔记系列

    一.此书到底何方神圣? <你必须知道的.NET>来自于微软MVP—王涛(网名:AnyTao,博客园大牛之一,其博客地址为:http://anytao.cnblogs.com/)的最新技术心 ...

  10. Web高级征程:《大型网站技术架构》读书笔记系列

    一.此书到底何方神圣? <大型网站技术架构:核心原理与案例分析>通过梳理大型网站技术发展历程,剖析大型网站技术架构模式,深入讲述大型互联网架构设计的核心原理,并通过一组典型网站技术架构设计 ...

随机推荐

  1. Luogu-1975 [国家集训队]排队

    Luogu-1975 [国家集训队]排队 题面 Luogu-1975 题解 题意:给出一个长度为n的数列以及m个交换两个数的操作,问每次操作后逆序对数量 时间,下标和数的大小三维偏序,,,把交换操作看 ...

  2. ZC_疑问

    1. 应该可以将所有的 jni需要的函数都放在一个 dll中(Windows下),然后 多个java项目就只要调用一个dll了. 可以测试一下 2.

  3. srm开发(基于ssh)(3)

    联系人管理 (1)客户和联系人一对多配置(重点) (2)新增联系人 -新增功能实现 -Struts2实现文件上传 (3)联系人列表 -no session问题 (4)客户和联系人级联删除 联系人管理模 ...

  4. java 在Excel中插入图片 POI实现

    一.POI简介 Jakarta POI 是apache的子项目,目标是处理ole2对象.它提供了一组操纵Windows文档的Java API 目前比较成熟的是HSSF接口,处理MS Excel(97- ...

  5. GO学习笔记:面向对象--method

    现在假设有这么一个场景,你定义了一个struct叫做长方形,你现在想要计算他的面积,那么按照我们一般的思路应该会用下面的方式来实现: package main import "fmt&quo ...

  6. 包嗅探和包回放 —tcpdump、tcpreplay--重放攻击

    攻击方式:tcpdump 进行嗅探,获取报文消息:然后用tcpreplay回放攻击 arp欺骗可以使用 arpspoof kali linux有这三个工具 转载地址https://www.cnblog ...

  7. js的onclick字符串参数的解决办法

    <a href='#' onclick='onedit(\""+ name + "\")';>编辑</a>" 一些写法实例~~ ...

  8. colorlog的三个例子

    例1:默认的log_colors import logging from logging.handlers import RotatingFileHandler from colorlog impor ...

  9. react 总结

    1.React 里直接修改 this.state 和调用 setState() 修改 state 的值有什么区别? 使用对this.state赋值并没有什么作用,官方提醒,应该把this.state当 ...

  10. saltstack笔记

    Saltstack类似于puppet salt的核心功能使用命令 发送到远程系统是并行的而不是串行的使用安全加密的协议使用最小最快的网络载荷提供简单的编程接口 Python编写,相当轻量级通讯层采用z ...