The C# Programming Language Notes

The C# Programming Language (Covering C# 4.0) 4th Edition The C# Programming Language (Covering C# 4.0) 4th Edition.rar 好书推荐 立即下载

1,不彻底的abstract

即使是abstract class,也不能对实现的接口的某个成员视而不见,即下面这样是不允许的:

interface in_one{
  void A();
}

abstract class base_one : in_one{
}

这一点上还是Java方便,不管C#的初衷是什么

2,out参数与指针的指针

out子类不能转化为out基类,如果允许转换的化,将无法保证类型安全性;即out参数相当于指针的指针,而父类的指针与子类的指针是没有继承关系的,所以不能转化

3,强制针对接口编程

针对接口编程只是一个一般性的原则,但C#提供了一种机制,强迫客户程序员根据接口来引用你的实现类:显式接口成员

 interface A{
  void a();
 }

 class A_Sub:A {
  void A.a() {
  }
 }
  static void Main(string[] args)
  {
   ((A)new A_Sub()).a(); //OK!
   new A_Sub().a();      //Error!
  }

显式接口成员实现程序跟其他成员相比,有不同的访问能力特性。因为显式接口成员不能通过实现类访问,所以,它们从感觉上是私有的。但是,由于它们可以通过接口引用访问,从感觉上它们又是公共的。
显式接口成员实现程序主要服务于两个目的:
a,类或结构实现一个客户不感兴趣的内部接口
b,用相同的签名消除接口成员的歧义
为了使显式接口成员实现程序有效,类或成员必须在它的基本类列表中命名一个接口,这个列表中包含一个成员,它的全部有效名称、类型和参数类型与显式接口成员实现程序的那些要完全一致

4,@ 取消转义

取消字符串转义尚可理解,不过连关键字都变成普通标识了,实在看不出有多大意义

5,struct的构造函数

自定义的ctor并不能隐藏默认的无参构造函数,稍有意外,却也在情理之中,默认无参构造函数对于struct有良好定义的语义

6,const,readonly

const相当于C++的static const
readonly相当于C++的const
所以,const相当于static readonly,当然,还是有些区别,const编译时获得值,static readonly运行时
 public class Color {
  public const Color Black = new Color(0, 0, 0);   //error
  public static readonly Color White = new Color(255, 255, 255); //ok
  private Color(byte r, byte g, byte b) {
  }
 }

7,自然的boxing,unboxing

string s = "abc";
object o = s;

int i = 123;
object o = i;

对于string的例子都不会吃惊,为什么要特殊对待int的例子呢?string是System.String的别名,只要把int当作System.Int32的别名,一切不都很自然了吗?int确实是System.Int32的别名,int和string还是有区别的,boxing后的值会被复制,数组调用很明确的不会扩展到数值类型的数组

或许是效率的原因吧

8,智能的自定义转型

C++不允许一次转换中调用超过一次的自定义转型操作符,C#同样不允许,不同的是C#会在调用自定义转型操作符前后为源类型和目标类型各插入一次自动寻找的标准转型操作,如果需要的话;简单的说;

9,操作符重载

C++里内存由程序员管理,允许重载new操作符,C#则理所当然的禁止了对new的重载
C++里算术运算符+-*/等重载后,其结合形式+=,-=,*=,/=不会被自动重载,C#为了保证语义一致性,自动重载了它们的结合形式

C++里短路逻辑运算符&&,||重载后不再具有短路的特性,C#干脆禁止了对它们的重载,只能通过以下形式变通,居然保持了短路的语义:
 class Test {
  public static bool operator false(Test test){
   return false;
  }
  public static bool operator true(Test test){
   return false;
  }
  public static Test operator & (Test lhs, Test rhs){
   return lhs;
  }
  public static Test operator | (Test lhs, Test rhs){
   return lhs;
  }
  static void Main(string[] args)
  {
   if(new Test() && new Test()){
   }
  }
 }

10,作用域

与Java有点不一样,嵌套块中名称相同的标识符都必须引用相同的实体,这项规则保证一个表达式上下文中名称的意义在一个块中是相同的:
class Test
{
 double x;
 void F(bool b) {
  x = 1.0;
  if (b) {
   int x = 1;
  }
 }
}
是错误的,因为x在外部块中(在if语句中包含嵌套块的扩展)引用了不同的实体。相反,例子
class Test
{
 double x;
 void F(bool b) {
  if (b) {
   x = 1.0;
  }else {
   int x = 1;
  }
 }
}
是允许的,因为名称x在外部块中永远不会使用

11,离开finally

与Java一样,finally中抛出异常,原先的异常(假如有的话)将被终止;不一样的是,不允许使用return,goto等离开finally,不知为什么

12,子包与外围包

与Java不一样,子包居然能访问外围包,不用using,方便,但合理否?

13,属性权限

get/set好像不能设置不同的权限,比如,我想internal set,而public get,不知怎么弄

14,序列化

当绝大部分域可以使用默认序列化,少数需要特殊处理时,将那少数几个域做成internal独立对象,令其自定义序列化,然后原对象中包含这个独立对象

15,int[][]是一维数组

int[,]才是二维的,矩阵
int[][]实际是锯齿

  int[][] one = new int[7][];
  int[,] two = new int[3,2];

维指示符在最后的非数组元素前被从左到右读。例如类型int[][,,][,]是一个int类型的两维数组的三维数组的单维数组

数组调用很明确的不会扩展到数值类型的数组,例如,不存在可以允许把int[]看作object[]的转换

数组初始化程序必须有与数组维数一样的嵌套级别。最外层嵌套与最左边的维数对应,而最里层的嵌套与最右边的维数对应

16,new virtual有没有意义?

class A
{
 public virtual void F() { Console.WriteLine("A.F"); }
}
class B: A
{
 public override void F() { Console.WriteLine("B.F"); }
}
class C: B
{
 new public virtual void F() { Console.WriteLine("C.F"); }
}
class D: C
{
 public override void F() { Console.WriteLine("D.F"); }
}
class Test
{
 static void Main() {
  D d = new D();
  A a = d;
  B b = d;
  C c = d;
  a.F();
  b.F();
  c.F();
  d.F();
 }
}
类C和D包含两个有相同签名的虚拟方法:一个被A引入而一个被C引入。被C引入的方法隐藏了从A继承的方法。这样,D中的覆盖声明覆盖了被C引入的方法,而D覆盖被A引入的方法是不可能的。例子产生下面的输出:
B.F
B.F
D.F
D.F

什么情况下,什么理由,我们需要new virtual?

17,override时无法改变访问修饰

即使是放宽

18,x+=y 结果有可能是void

“在一个形式为x += y 或 x -= y的操作中,当x是一个事件成员而引用在x所在的类型外面发生时,操作的结果就是void;这个规则禁止外部代码直接检查事件成员”   ???

19,构造函数执行顺序

可以把一个实例变量初始化函数和一个构造函数初始化函数,看作是自动插在构造函数主体中的第一条语句前。例子
class A
{
 int x = 1, y = -1, count;
 public A() {
  count = 0;
 }
 public A(int n) {
  count = n;
 }
}
class B: A
{
 double sqrt2 = Math.Sqrt(2.0);
 ArrayList items = new ArrayList(100);
 int max;
 public B(): this(100) {
  items.Add("default");
 }
 public B(int n): base(n – 1) {
  max = n;
 }
}
包含了许多变量初始化函数,并且也包含了每个形式(base和this)的构造函数初始化函数。这个例子与下面介绍的例子相关,在那里,每条

注释指明了一个自动插入的语句(自动插入构造函数调用所使用的语法不是有效的,至少用来演示这个机制)。
class A
{
 int x, y, count;
 public A() {
  x = 1;        // Variable initializer
  y = -1;        // Variable initializer
  object();       // Invoke object() constructor
  count = 0;
 }
 public A(int n) {
  x = 1;        // Variable initializer
  y = -1;        // Variable initializer
  object();       // Invoke object() constructor
  count = n;
 }
}
class B: A
{
 double sqrt2;
 ArrayList items;
 int max;
 public B(): this(100) {
  B(100);        // Invoke B(int) constructor
  items.Add("default");
 }
 public B(int n): base(n – 1) {
  sqrt2 = Math.Sqrt(2.0);   // Variable initializer
  items = new ArrayList(100); // Variable initializer
  A(n – 1);       // Invoke A(int) constructor
  max = n;
 }
}
注意变量初始化函数被转换为赋值语句,并且那个赋值语句在对基类构造函数调用前执行。这个顺序确保了所有实例域在任何访问实例的语句

执行前,被它们的变量初始化函数初始化。例如:
class A
{
 public A() {
  PrintFields();
 }
 public virtual void PrintFields() {}
}
class B: A
{
 int x = 1;
 int y;
 public B() {
  y = -1;
 }
 public override void PrintFields() {
  Console.WriteLine("x = {0}, y = {1}", x, y);
 }
}
当new B() 被用来创建B的实例时,产生下面的输出:
x = 1, y = 0
因为变量初始化函数在基类构造函数被调用前执行,所以x的数值是1。可是,y的数值是0(int的默认数值),这是因为对y的赋值直到基类构造函数返回才被执行。

静态构造函数自动被调用,不能被显式调用。虽然提供了许多约束条件,但是静态构造函数执行的确切时间和顺序是不确定的:
一个类的静态构造函数在这个类的任何实例被创建前执行。
一个类的静态构造函数在类的任何静态成员被引用前执行。
一个类的静态构造函数在它的所有派生类的静态构造函数执行之后执行。
一个类的静态构造函数从不会被执行一次以上。

20,struct可以实现接口

稍有意外,看来struct基本类似于“对基本数据类型域有深拷贝语义的sealed类”,说完这句话都觉得别扭

21,接口

与Java不一样,接口不能声明静态常量和内部类,接口的成员必须是方法、属性、事件或索引

22,枚举

不明白为什么非得跟整型扯上点关系,为了&|操作?即使这样,也可以内部用整型来实现,不必暴露出来

23,Delegate

观察者模式在语言层面的支持,优于java.util.Observable,Delegate是类型安全的,不同于java.util.Observable,Delegate不是异常安全的

24,条件属性

通过对被调用方进行标记,代替传统的调用方条件编译,使代码整洁,单点开关,又消除了宏的缺点
 

Programming.C#.中文版(第4版) 立即下载

相关推荐

The Csharp Programming Language

一样的c#经典书籍,值得看一下

《The C# Programming Language》及其它

学过C的,没有不知道K&R的《The C Programming Language》的……学过C++的,没有不知道Bjarne Stroustrup的《The C++ Programming Language》的……[@...

ciren8547的博客 216

Dual-stream multiple instance learning networks for tumor detection in Whole Slide Image——论文笔记

关于多示例学习的资料网上比较少,但是在医学图像方面还是有人在应用的。主要是因为一般比较大,几个G都是十分常见的,这么大图片是无法直接训练,一般都会进行切图,所以天然契合多示例学习bag和instance的概念。最近看了一篇论文刚好关于这方面的,所以做下笔记。 github地址:https://github.com/binli123/dsmil-wsi paper:https://arxiv.org/abs/2011.08939 背景知识 在多示例学习(MIL)中,一组训练样本被视为包含多个instance的

weixin_41693877的博客 4170

The C# Programming Language (3rd Edition)

版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章原始出版、作者信息和本声明。否则将追究法律责任。http://blog.youkuaiyun.com/topmvp - topmvpC# is a simple, modern, object-oriented, and type-safe programming language that combines the high productivi

TopMVP 1151

java链接opc报异常org.jinterop.dcom.common.JIException: Access is denied解决

记录一下这次从发现问题到解决问题的过程 项目是通过java链接OPC,读取数据,并且发送数据的 程序一直运行正常,最近客户反馈说无法读取数据,通过查看,发现访问异常了。花了2天的时间才解决了这个异常。 org.jinterop.dcom.common.JIException: Access is denied, please check whether the [domain-username-password] are correct. Also, if not already done please c

机器学习菜鸟 1万+

AB脉冲详解(编码器,PLC,上位机)

编码器线有些是用不到的。Z脉冲:360度中,只有1度是输出,输出能力是。编码器实际就是发光二极管,所以电流超过20ma会缩短寿命或损坏。

cfqq1989的博客 1万+

电子书下载:The C# Programming Language, 4th Edition

下载:http://www.ctdisk.com/file/5491515 转载于:https://www.cnblogs.com/MaxWoods/archive/2011/01/11/1932639.html

weixin_30739595的博客 218

避开这些坑,你的Python爬虫才能稳定爬取IEEE Xplore(含反爬策略与MongoDB存储实战)

本文详细介绍了如何构建稳定的Python爬虫系统以爬取IEEE Xplore学术论文,包括反爬策略、MongoDB存储优化和断点续传机制。通过动态等待时间算法、请求头指纹管理和会话保持策略,有效应对IEEE的反爬机制。同时,优化MongoDB数据结构和索引,提升存储效率。最后,强调法律合规与伦理考量,确保爬虫合法合规运行。

weixin_29031057的博客 1096

The C# Programming Language Notes II

C# 2.0 的表达能力已经在我们的项目中得到检验,先看看1.1时哪些问题没弄明白: Q: 4,@ 取消转义 取消字符串转义尚可理解,不过连关键字都变成普通标识了,实在看不出有多大意义 A: 与其他编程语言建立接口时很有用 .Net多语言平台, foreach 在C++中不是关键字,可以作为函数名称,那么导入到C#程序中就是 @foreach  Q: 1

切尔斯基 2935

深度学习论文: AnomalyDINO: Boosting Patch-based Few-shot Anomaly Detection with DINOv2

通过将DINOv2模型适应到一次性和少量异常检测中,并专注于工业应用少量异常检测。实验表明,这种方法不仅与现有技术相匹敌,甚至可以在许多设置中超越它们。我们提出的仅视觉方法AnomalyDINO基于补丁相似性,能够实现图像级别的异常预测和像素级别的异常分割。该方法在方法论上很简单,无需训练,因此不需要任何额外的数据进行微调或元学习。

mingo_敏 1905

ROS入门教程(七)—— Gazebo与RViz联合仿真

通过Gazebo与RViz联合仿真实现机器人运动。

吾门的博客 1万+

The Java Programming Language Notes

 1,static member可使用该类对象的空引用来引用该类static memberSomeClass obj = null;obj.staticMethod();obj.staticData = 1;用对象引用静态成员是不被推荐的,但为什么不像C#那样禁止掉呢?2,多重继承面对从多个接口继承而来的签名相同的方法,子类似乎只能提供一份实现,这样语义的正确性是如何保证的呢?C#

切尔斯基 7121

基于NAS的OpenClaw部署方案:家庭服务器架构设计

本文提出了一种基于NAS的家庭服务器架构方案,用于部署OpenClaw AI系统。文章分析了NAS作为部署平台的六大优势:集中化数据管理、大容量存储、多用户并发访问、7×24小时稳定运行、低功耗设计以及丰富的扩展能力。针对不同用户需求,详细对比了主流NAS型号(如Synology DS923+、QNAP TS-870等)和DIY方案的硬件配置,并给出了最低/推荐配置标准。在部署方案部分,重点介绍了Synology DSM和TrueNAS两种系统的初始化步骤,以及通过Docker容器安装Python、Redi

博客 2509
上一篇: 独孤九剑与软件开发
下一篇: 泛型编程 vs. 面向对象
Image_Graphics
博客等级 码龄20年 18粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值