国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C# > 正文

C#語法相比其它語言比較獨特的地方(二)

2020-01-24 02:00:37
字體:
來源:轉載
供稿:網友

之前有個兄弟給我的卷一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);

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 政和县| 利辛县| 西昌市| 四川省| 南城县| 公主岭市| 阿克| 汉沽区| 呼伦贝尔市| 祁门县| 潮安县| 承德市| 阿合奇县| 台东市| 通江县| 永康市| 轮台县| 合川市| 江陵县| 垣曲县| 枝江市| 洪雅县| 商都县| 汨罗市| 克拉玛依市| 金堂县| 文昌市| 监利县| 辉县市| 浏阳市| 襄樊市| 长兴县| 勐海县| 中西区| 潼南县| 红桥区| 陈巴尔虎旗| 邻水| 淳化县| 安福县| 丹棱县|