C#语法相比其它语言比较独特的地方(二)

 更新时间:2020年6月25日 11:31  点击:1591

之前有个兄弟给我的卷一re了帖子,我当时没有g,m,直到他把它删掉才后悔莫及,人生最痛苦的事情莫过于此。。。。。。

好,即便如此,我们还是满怀希望的向前奔去。接着写卷二。

还要提一下,上次最后说到的delegate,在我了解了它的实现和用途以及看到我的偶像的一些访问记录后,我对它有了很深的理解,并且在事件处理机制上,我更偏向于我偶像这边,有兄弟说MFC是switch,java是listener,其实java这些listener在processEvent里面还不是一个个switch然后调用,都是switch,那switch就不能说是特点了,最大的特点还是是否直接使用函数指针来进行响应这点上。往下又说信号处理,以前的8259A发生中断查中断向量表进行到头来也是地址转移阿,这也没特点,到后来调用都是地址转移,而速度的差别就在于在同样不可避免具有某些相同层次实现的情况下,机制不同架构不同造成的效率差别,这就完全取决于实力了。

1,internal与protected,private

C#默认的,当定义一个class的时候,如果你没有加任何访问修饰子,那么该class的访问权限即为internal,当然你可以显式制定为internal。internal是什么呢?internal就是说在当前工程中,都可访问,不管你自己用了几个名称空间,都无所谓。

但是在定义一个class中的成员变量的时候,假如你什么都不写,那么这个成员变量默认的权限就是private。如果你要这个成员在当前工程中也可以被访问,则必须使用internal关键字来显式的修饰它。

另外,c#里面的protected访问权限仍然和以前的c++中是一致的含义,表示只有继承者才有访问权限。即便是同一个工程,同一个名称空间中的别的类,都别想看到这个protected成员,颇为严格的一个访问限制。

internal和protected基本控制访问是在不同的领域,他们两个是可以同时用来修饰一个对象的。比如

复制代码 代码如下:

    class PPP
    {
        internal protected static int c=3;

    }


没有交集,也不会互斥。

这跟java是截然不同的,其实我本可以完全不提java,但由于我自己的背景和一个通盘概括,我还是把java的拿出来与c#进行类比。毕竟本文标题是“特别之处”,当然,这里我也不知道你会认为是c#特别,还是java特别了。

java中没有完全相同于这个internel似的访问控制,它有一种独特的package访问控制。不管是类还是类的成员,如果你不写访问修饰,那么它就是package访问级别的,package访问级别的含义是在本package中都可以访问。java中没有那种类似internal的“在本工程”或者本“jar”中可以访问的这种级别,只有package级别。
而java中的protected也是比c#中的protected要宽容得多,java中的protected的含义其实等价于c#中的protected并上java中的package。有人打了这么一个比方,说大宅门,有很多资源都是protected的,这些资源不但可以造福四邻(同在一个package中),还可以给自己的儿子阿,孙子阿(儿子孙子通过继承得到资源)即便他们远走他乡。

2,enum

我们学过C,C中定义enum中的元素符号的时候,这个符号不能够与当前作用域中的其他符号相同,并且,所有这些enum中的符号可以直接拿来当常数使用,就好像是#define了一个整形常量一般。特别是当不制定enum类型标记的时候,那简直就是个#define。

C++中几乎与C中相同,不同的是,当定义一个这种enum对象的时候,不用
写  enum 类型标记 对象;
而只用写  类型标记 对象; 即可。

就好像以前必须写 struct 类型标记 对象;

而在c++中就可以只用写  类型标记 对象;  一样但是不管是在c#或者是java中,首先它们都不可以省略类型标记。其次,不用确保必须不同于同个作用域的其他标记符。再者,不可以直接把enum中的元素符号直接拿过来当常量。起码也要写,类型标记.元素符号 才行。
比如

复制代码 代码如下:

enum XXX{A,B,C,D}
....
Console.writeLine(XXX.A);

但是C#中又有其特别之处,它保留了部分c的enum才有的功能。那就是可以用运算符+、-来对enum对象进行运算,这是java绝对做不到了,而且还可以转换回int型别。比如
复制代码 代码如下:

enum weekdays{sunday,monday.....saturday}
for(weekdays wd=weekdays.sunday;wd<=weekdays.saturday;wd++)
   ...
(int)weekdays.sunday   //结果是0

也可以赋值
复制代码 代码如下:

enum open_modes{
  intput=1,output,append,
  last_input_mode=input,last_output_mode=output
}

如果你觉得默认实现是int型太耗,可以用byte型
复制代码 代码如下:

enum weekdays:byte{
....
}

3.string的==
我们都知道Equals方法可以给人覆盖用来判断两个对象是否是同值,而==作用于两个对象只能比较两个对象的ref是否相等。

我们在java中比较两个字符串是否相等用的是"hello".equals(aaa);
但是在c#中,string对象的==运算已经被强行重写,它就是表示equals,
这就是说,在c#中,实现字符串值比较的话,只需要写成"hello"==aaa就行了,
这样设计的目的是为了更直观。

4.传引用

在java中有个非常经典的问题,这个问题的到访真是让我习以为常。
那就是字符串处理函数的问题。
在java或者c#中,有人

复制代码 代码如下:

void processString(String a)
{
    a=a+"asdfjsdf";
}

或者说是数字交换问题
复制代码 代码如下:

void processInt(int a,int b)
{
  int temp=a;
   a=b;b=temp;
}

前者还有说的,后者则是连c的基础都没打好了,后者的话建议去补习C。
前者我来说一下,不管是java中还是c#中,string对象都是immutable的,即一经产生,就无法改变,那么+运算符做了什么呢?它将生成一个新的string对象,然后把+两边的string的内容都填进来。

也就是说a+"asdfdjkf"这个东西是一个全新的东西,如果写成a+="asdfj"或者a=a+"sdfjk"那么原来的a和这个"asdjf"就可以被GC了。

再说java和c#中的对象型别,java和c#中所有的对象型别都是ref型别,也就是说。

复制代码 代码如下:

String a;

这么一句话,只是定义了一个ref,它基本上不占用任何资源,也没有生成任何真正的对象,它只是一个ref。

String a="dkfjsdf";的时候,在受控堆上生成一个对象"dkfjsdf",然后返回这个对象的ref给a。

我们再看刚才那个字符串处理,a只是一个类似局部变量的形式参数,你将a的ref设为一个新值,然后函数返回,形式参数a没了,原来的实际参数啥变化都没有。

但是你说,我就是要这样处理,这么办呢?在java中,就没法这样处理String,不过StringBuffer之类的倒是可以,因为我们虽然无法改变实际参数的ref值,但是却可以通过相同值ref更改对象内部成员,对于immutable的我们没办法,但对于mutable的我们就可以捏了。

而在c#中,非常恭喜你可以得逞了。就像我们刚才设想的那样去处理string是可以的,不过要这样做。

复制代码 代码如下:

void processString(ref string a)
{
  a+="sdjkf";
}

加上了ref,就取消了形式参数的产生和压退栈,就好像c++中的string &了,相当于是直接将实际参数交给你了。
这样我们对它为所欲为都是可以的,这样我们的processString就得逞了。
不过在填实际参数的时候,需要写成这样
复制代码 代码如下:

string h="haha";
processString(ref h);
Console.WriteLine(h);

我们就可以看到h被改变了。

5,out参数

out参数就好像直接通过c#语言实现了com接口定义中的out的语义一样。
就是输出参数,我们知道不管是windows api还是com,函数返回值通常用来处理异常的,而真正处理的结果是通过输出参数带回的,输出参数实现有很多种方式,比如传地址,传引用,当然com中从来不用c++中诡异的那个&引用。

out参数跟我们之前提到的ref参数唯一不同的就在于,ref参数在填到实参之前,必须初始化,而out参数无此要求,它就是用来带回结果的,你可以定义一个未初始化的局部变量,然后用out 变量名的写法填进去,调用完毕,值就放在这个变量里了。

比如我们改改刚才的processString来说明out参数用法

复制代码 代码如下:

void processString( out string a)
{
   a="xxx";
}

string a;
processString(out a);
Console.WriteLine(a);

[!--infotagslink--]

相关文章

  • C#实现简单的登录界面

    我们在使用C#做项目的时候,基本上都需要制作登录界面,那么今天我们就来一步步看看,如果简单的实现登录界面呢,本文给出2个例子,由简入难,希望大家能够喜欢。...2020-06-25
  • 浅谈C# 字段和属性

    这篇文章主要介绍了C# 字段和属性的的相关资料,文中示例代码非常详细,供大家参考和学习,感兴趣的朋友可以了解下...2020-11-03
  • C#中截取字符串的的基本方法详解

    这篇文章主要介绍了C#中截取字符串的的基本方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-11-03
  • C#实现简单的Http请求实例

    这篇文章主要介绍了C#实现简单的Http请求的方法,以实例形式较为详细的分析了C#实现Http请求的具体方法,需要的朋友可以参考下...2020-06-25
  • C#连接SQL数据库和查询数据功能的操作技巧

    本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
  • C#中new的几种用法详解

    本文主要介绍了C#中new的几种用法,具有很好的参考价值,下面跟着小编一起来看下吧...2020-06-25
  • 使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序)

    这篇文章主要介绍了使用Visual Studio2019创建C#项目(窗体应用程序、控制台应用程序、Web应用程序),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C#开发Windows窗体应用程序的简单操作步骤

    这篇文章主要介绍了C#开发Windows窗体应用程序的简单操作步骤,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-04-12
  • C#从数据库读取图片并保存的两种方法

    这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
  • C#和JavaScript实现交互的方法

    最近做一个小项目不可避免的需要前端脚本与后台进行交互。由于是在asp.net中实现,故问题演化成asp.net中jiavascript与后台c#如何进行交互。...2020-06-25
  • C++调用C#的DLL程序实现方法

    本文通过例子,讲述了C++调用C#的DLL程序的方法,作出了以下总结,下面就让我们一起来学习吧。...2020-06-25
  • 轻松学习C#的基础入门

    轻松学习C#的基础入门,了解C#最基本的知识点,C#是一种简洁的,类型安全的一种完全面向对象的开发语言,是Microsoft专门基于.NET Framework平台开发的而量身定做的高级程序设计语言,需要的朋友可以参考下...2020-06-25
  • C#变量命名规则小结

    本文主要介绍了C#变量命名规则小结,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-09-09
  • C#绘制曲线图的方法

    这篇文章主要介绍了C#绘制曲线图的方法,以完整实例形式较为详细的分析了C#进行曲线绘制的具体步骤与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
  • C# 中如何取绝对值函数

    本文主要介绍了C# 中取绝对值的函数。具有很好的参考价值。下面跟着小编一起来看下吧...2020-06-25
  • c#自带缓存使用方法 c#移除清理缓存

    这篇文章主要介绍了c#自带缓存使用方法,包括获取数据缓存、设置数据缓存、移除指定数据缓存等方法,需要的朋友可以参考下...2020-06-25
  • c#中(&&,||)与(&,|)的区别详解

    这篇文章主要介绍了c#中(&&,||)与(&,|)的区别详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
  • 经典实例讲解C#递归算法

    这篇文章主要用实例讲解C#递归算法的概念以及用法,文中代码非常详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下...2020-06-25
  • C#学习笔记- 随机函数Random()的用法详解

    下面小编就为大家带来一篇C#学习笔记- 随机函数Random()的用法详解。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
  • C#中list用法实例

    这篇文章主要介绍了C#中list用法,结合实例形式分析了C#中list排序、运算、转换等常见操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25