C Sharp
出自 MBA智库百科(https://wiki.mbalib.com/)
目錄 |
C#是微軟公司發佈的一種面向對象的、運行於.NET Framework之上的高級程式設計語言。並定於在微軟職業開發者論壇(PDC)上登臺亮相。C#是微軟公司研究員Anders Hejlsberg的最新成果。C#看起來與Java有著驚人的相似;它包括了諸如單一繼承、介面、與Java幾乎同樣的語法和編譯成中間代碼再運行的過程。但是C#與Java有著明顯的不同,它借鑒了Delphi的一個特點,與COM(組件對象模型)是直接集成的,而且它是微軟公司 .NET windows網路框架的主角。
C#是一種安全的、穩定的、簡單的、優雅的,由C和C++衍生出來的面向對象的編程語言。它在繼承C和C++強大功能的同時去掉了一些它們的複雜特性(例如沒有巨集以及不允許多重繼承)。C#綜合了VB簡單的可視化操作和C++的高運行效率,以其強大的操作能力、優雅的語法風格、創新的語言特性和便捷的面向組件編程的支持成為.NET開發的首選語言。
C#是面向對象的編程語言。它使得程式員可以快速地編寫各種基於MICROSOFT .NET平臺的應用程式,MICROSOFT .NET提供了一系列的工具和服務來最大程度地開發利用計算與通訊領域。
C#使得C++程式員可以高效的開發程式,且因可調用由C/C++編寫的本機原生函數,因此絕不損失C/C++原有的強大的功能。因為這種繼承關係,C#與C/C++具有極大的相似性,熟悉類似語言的開發者可以很快的轉向C#。
C#是微軟公司在2000年6月發佈的一種新的編程語言,主要由安德斯·海爾斯伯格(Anders Hejlsberg)主持開發,它是第一個面向組件的編程語言,其源碼會編譯成msil再運行。它借鑒了Delphi的一個特點,與COM(組件對象模型)是直接集成的,並且新增了許多功能及語法糖,而且它是微軟公司.NET windows網路框架的主角。
C#讀作C Sharp。最初它有個更酷的名字,叫做COOL。微軟從1998年12月開始了COOL項目,直到2000年2月,COOL被正式更名為C#。在1998年,Delphi語言的設計者Hejlsberg帶領著Microsoft公司的開發團隊,開始了第一個版本C#語言的設計。在2000年9月,國際信息和通信系統標準化組織為C#語言定義了一個Microsoft公司建議的標準。最終C#語言在2001年得以正式發佈。
原Broland公司的首席研發設計師安德斯·海爾斯伯格(Anders Hejlsberg)在微軟開發了Visual J++ 1.0,很快的Visual J++由1.1版本升級到6.0版。SUN公司認為Visual J++ 違反了Java開發平臺的中立性,對微軟提出了訴訟。2000年6月26日微軟在奧蘭多舉行的“職業開發人員技術大會”(PDC 2000)上,發表新的語言C#。C#語言取代了Visual J++,語言本身深受 Java、C 和 C++ 的影響。
C#是兼顧系統開發和應用開發的最佳實用語言,並且很有可能成為編程語言歷史上的第一個“全能”型語言。看過這篇簡史,不要把C#看成年輕後生了——只要是“馬拉多納”,就早晚當“球王”。C#1.0,純粹的面向對象。
1998年底,微軟正在忙於新一代COM的設計工作,COM一直是組件化開發中非常成功的一種技術;但由於它僅提供了二進位層面上的統一,因此無法將類型信息和用於支持基礎平臺和開發工具的信息放到組件中,Java逐步走向成熟。微軟學習Java的做法,將虛擬機的概念引入到了COM領域;同時,微軟提出了“元數據”的概念,用於描述組件的類型信息和工具支持信息,並決定將其放入到組件當中。
1998年12月,微軟啟動了一個全新的語言項目——COOL,這是一款專門為CLR設計的純面向對象的語言,也正是本文的主角——C#的前身。
1999年7月份,微軟完成了COOL語言的一個內部版本。
2000年2月份,微軟才正式將COOL語言更名為C#。據說起這個名字是因為C#開發小組的人很討厭搜索引擎,因此把大部分搜索引擎無法識別的“#”字元作為該語言名字的一部分;還有一種說法是在音樂當中“#”是升調記號,表達了微軟希望它在C的基礎上更上一層樓的美好願望——當然這些都只是傳說,無從考證。又是歷經了一系列的修改,微軟終於在2000年7月發佈了C#語言的第一個預覽版。
C#旨在設計成為一種“簡單、現代、通用”,以及面向對象的程式設計語言,此種語言的實現,應提供對於以下軟體工程要素的支持:強類型檢查、數組維度檢查、未初始化的變數引用檢測、自動垃圾收集(Garbage Collection,指一種自動記憶體釋放技術)。軟體必須做到強大、持久,並具有較強的編程生產力。此種語言為在分散式環境中的開發提供適用的組件開發應用。
為使程式員容易遷移到這種語言,源代碼的可移植性十分重要,尤其是對於那些已熟悉C和C++的程式員而言。對國際化的支持非常重要。C#適合為獨立和嵌入式的系統編寫程式,從使用複雜操作系統的大型系統到特定應用的小型系統均適用。
類:在C#中類的聲明與C++和Java很相似。但是,不象C++,C#結構體與類是不支持繼承。但是,與Java相同的是,一個結構體可以實現介面(interface)。Java的關鍵字import已經被替換成using,它起到了同樣的作用。
類可以是抽象的和不可繼承的:一個被申明成abstract的類不能被實例化,它只能被用做一個基類,C#關鍵字lock就像Java關鍵字final,它申明一個類不是抽象的,但是它也不能被用做另一個類的基類界面:就象在Java中一樣,一個界面是一組方法集合的抽象定義。當一個類或結構體實現一個界面的時候,它必須實現這個界面中定義的所有方法。一個單一的類可以實現幾個界面,也許以後會出現一些微妙的差別,但是這個特點看起來與Java相比沒有變化。
在Java中,一個介面是一組方法集合的抽象定義.當一個類或結構體實現一個介面的時候,它必須實現這個介面中定義的所有方法.一個單一的類可以實現幾個介面.也許以後會出現一些微妙的差別,但是這個特點看起來與Java相比沒有變化。布爾運算:條件表達式的結果是布爾數據類型,布爾數據類型是這種語言中獨立的一種數據類型.從布爾類型到其他類型沒有直接的轉換過程.布爾常量true和false是C#中的關鍵字.錯誤處理:如Java中那樣,通過拋出和捕捉異常對象來管理錯誤處理過程.記憶體管理:由底層.NET框架進行自動記憶體垃圾回收。
布爾運算:條件表達式的結果是布爾數據類型,布爾數據類型是這種語言中獨立的一種數據類型,從布爾類型到其他類型沒有直接的轉換過程,布爾常量true和false是C#中的關鍵字。錯誤處理:如Java中那樣,通過拋出和捕捉異常對象來管理錯誤處理過程。
記憶體管理:由底層.NET框架進行自動記憶體垃圾回收。一個基本的C#類中包含數據成員、屬性、構造器和方法。屬性可以是靜態或實例成員。
介面:是其他類型為確保它們支持某些操作而實現的引用類型。介面從不直接創建而且沒有實際的表示形式,其他類型必須轉換為介面類型。
一個介面定義一個協定。實現介面的類或結構必須遵守其協定。介面可以包含方法、屬性、索引器和事件作為成員。
強類型:C#是一個強類型的語言,它的數值類型有一些可以進行隱式轉換,其他的必須顯式轉換,隱式轉換的類型只能是長度短的類型轉換成長的類型,int可以轉換成long、float、double、decimal,反之必須顯式的轉換。
編譯:程式直接編譯成標準的二進位可執行形式.但C#的源程式並不是被編譯成二進位可執行形式,而是一種中間語言(IL),類似於JAVA位元組碼。如果前面的Hello World程式被保存成一個文本文件並被命名為Hello.cs,它將被編譯成命名Hello.exe的可執行程式。
C#程式不能直接編譯成標準的二進位可執行形式,與 Java 類似,它被編譯成為中間代碼(Microsoft Intermediate Language),然後通過 .NET Framework 的虛擬機——被稱之為通用語言執行層(Common Language Runtime, CLR)——執行。
一個C#的結構體與C++的結構體是相似的,因為它能夠包含數據聲明和方法.但是,不象C++,C#結構體與類是不同的而且不支持繼承.但是,與Java相同的是,一個結構體可以實現介面。
預編譯:C# 中存在預編譯指令支持條件編譯,警告,錯誤報告和編譯行控制.可用的預編譯指令有:#define,#undef,#if,#elif,#else,#endif,#warning,#error,#line。
沒有了#include偽指令,無法再用#define 語句對符號賦值,所以就不存在源代碼替換的概念--這些符號只能用在#if和#elif偽指令里.在#line偽指令里的數字(和可選的名字)能夠修改行號還有#warning和#error輸出結果的文件名。
操作符重載:一些操作符能夠被重載,而另一些則不能.特別的是,沒有一個賦值運算符能夠被重載.能夠被重載的單目操作符是:+ - ! ~ ++ -- true false 能夠被重載的二元運算符是:+、 - 、*、 /、 %、 &、 |、 ^、 << 、>>、 ==、 !=、 >、 < 、>= 、<=。
類型:C# 中的類型一共分為兩類,一類是值類型(Value Type),一類是引用類型(Reference Type)。值類型和引用類型是以它們在電腦記憶體中是如何被分配的來劃分的。值類型包括 結構和枚舉,引用類型包括類、介面、委托 等。還有一種特殊的值類型,稱為簡單類型(Simple Type),比如 byte,int等,這些簡單類型實際上是FCL類庫類型的別名,比如聲明一個int類型,實際上是聲明一個System. Int32結構類型。因此,在 Int32類型中定義的操作,都可以應用在int類型上,比如 “123.Equals(2)”。
所有的值類型都隱式地繼承自System.ValueType類型(註意System.ValueType本身是一個類類型),System.ValueType和所有的引用類型都 繼承自 System.Object基類。不能顯式地讓結構繼承一個類,因為C#不支持多重繼承,而結構已經隱式繼承自ValueType。
NOTE:堆棧(stack)是一種後進先出的數據結構,在記憶體中,變數會被分配在堆棧上來進行操作。堆(heap)是用於為類型實例(對象)分配空間的記憶體區域,在堆上創建一個對象,會將對象的地址傳給堆棧上的變數(反過來叫變數指向此對象,或者變數引用此對象)。
中間代碼:微軟在用戶選擇何時MSIL應該編譯成機器碼的時候是留了很大的餘地.微軟公司很小心的聲稱MSIL不是解釋性的,而是被編譯成了機器碼.它也明白許多--如果不是大多數的話--程式員認為Java程式要不可避免的比C編寫的任何東西都要慢.而這種實現方式決定了基於MSIL的程式(指的是用C#,Visual Basic,"Managed C++"--C++的一個符合CLS的版本--等語言編寫的程式)將在性能上超過"解釋性的"Java代碼.當然,這一點還需要得到事實證明,因為C#和其他生成MSIL的編譯器還沒有發佈.但是Java JIT編譯器的普遍存在使得Java和C#在性能上相對相同.象"C#是編譯語言而Java是解釋性的,"之類的聲明只是商業技巧.Java的中間代碼和MSIL都是中間的彙編形式的語言,它們在運行時或其它的時候被編譯成機器代碼。
基本數據類型:C#擁有比C/C++或者Java更廣泛的數據類型.這些類型是bool、byte、ubyte、short、ushort、int、uint、long、ulong、float、double和decimal,像Java一樣,所有這些類型都有一個固定的大小.又像C和C++一樣,每個數據類型都有有符號和無符號兩種類型.與Java相同的是,一個字元變數包含的是一個16位的Unicode字元,C#新的數據類型是decimal數據類型,對於貨幣數據,它能存放28位10進位數字。
兩個基本類:一個名叫object的類是所有其他類的基類。而一個名叫string的類也象object一樣是這個語言的一部分.作為語言的一部分存在意味著編譯器有可能使用它,無論何時在程式中寫入一句帶引號的字元串,編譯器會創建一個string對象來保存它。
參數傳遞:方法可以被聲明接受可變數目的參數.預設的參數傳遞方法是對基本數據類型進行值傳遞。ref關鍵字可以用來強迫一個變數通過引用傳遞,這使得一個變數可以接受一個返回值。out關鍵字也能聲明引用傳遞過程,與ref不同的地方是,它指明這個參數並不需要初始值。
COM的集成:C#對Windows程式最大的賣點可能就是它與COM的無縫集成了,COM就是微軟的Win32組件技術.實際上,最終有可能在任何.NET語言里編寫COM客戶和伺服器端。C#編寫的類可以子類化一個已存在的COM組件;生成的類也能被作為一個COM組件使用,然後又能使用,比方說,JScript語言子類化它從而得到第三個COM組件。這種現象的結果是導致了一個運行環境的產生,在這個環境里的組件是網路服務,可用任何.NET語言子類化。
索引下標:一個索引與屬性除了不使用屬性名來引用類成員而是用一個方括弧中的數字來匿名引用(就象用數組下標一樣)以外是相似的。
代理和反饋:一個代理對象包括了訪問一個特定對象的特定方法所需的信息.只要把它當成一個聰明的方法指針就行了。代理對象可以被移動到另一個地方,然後可以通過訪問它來對已存在的方法進行類型安全的調用.一個反饋方法是代理的特例.event關鍵字用在將在事件發生的時候被當成代理調用的方法聲明中。
C#所開發的程式源代碼並不是編譯成能夠直接在操作系統上執行的二進位本地代碼。與Java類似,它被編譯成為中間代碼,然後通過.NETFramework的虛擬機——被稱之為通用語言運行時(CLR)——執行。 所有的.Net編程語言都被編譯成這種被稱為MSIL(Microsoft Intermediate Language )的中間代碼。因此雖然最終的程式在錶面上仍然與傳統意義上的可執行文件都具有“.exe”的尾碼名。但是實際上,如果電腦上沒有安裝.Net Framework,那麼這些程式將不能夠被執行。 在程式執行時,.Net Framework將中間代碼翻譯成為二進位機器碼,從而使它得到正確的運行。最終的二進位代碼被存儲在一個緩衝區中。所以一旦程式使用了相同的代碼,那麼將會調用緩衝區中的版本。這樣如果一個.Net程式第二次被運行,那麼這種翻譯不需要進行第二次,速度明顯加快。
關鍵字部分描述:
- abstract:可以和類、方法、屬性、索引器及事件一起使用,標識一個可以擴展但不能被實體化的、必須被實現的類或方法。
- as:一個轉換操作符,如果轉換失敗,就返回null。
- base:用於訪問被派生類或構造中的同名成員隱藏的基類成員。
- catch:定義一個代碼塊,在特定類型異常拋出時,執行塊內代碼。
- checked:既是操作符又是語句,確保編譯器運行時,檢查整數類型操作或轉換時出現的溢出。
- const:標識一個可在編譯時計算出來的變數值,即一經指派不可修改的值。
- delegate:指定一個聲明為一種委托類型。委托把方法封裝為可調用實體,能在委托實體中調用。
- enum:表示一個已命名常量群集的值類型。
- event:允許一個類或對象提供通知的成員,他必須是委托類型。
- explicit:一個定義用戶自定義轉換操作符的操作符,通常用來將內建類型轉換為用戶定義類型或反向操作,必須再轉換時調用顯示轉換操作符。
- extern:標識一個將在外部(通常不是c#語言)實現的方法。
- finally:定義一個代碼塊,在程式控制離開try代碼快後執行。參見try和catch。
- fixed:在一個代碼塊執行時,在固定記憶體位置為一個變數指派一個指針。
- foreach:用於遍歷一個群集的元素。
- goto:一個跳轉語句,將程式執行重定向到一個標簽語句。
- implicit:一個操作符,定義一個用戶定義的轉換操作符,通常用來將預定義類型轉換為用戶定義類型或反向操作,隱式轉換操作符必須在轉換時使用。
- interface:將一個聲明指定為介面類型,即實現類或構造必須遵循的合同。
- internal:一個訪問修飾符。
- namespace:定義一個邏輯組的類型和命名空間。
- operator:用來聲明或多載一個操作符。
- out:標識一個參數值會受影響的參數,但在傳入方法時,該參數無需先初始化。
- params:聲明一個參數數組。如果使用,必須修改指定的最後一個參數,允許可選參數。
- readonly:標識一個變數的值在初始化後不可修改。
- ref:標識一個參數值可能會受影響的參數。
- sealed:防止類型被派生,防止方法和property被覆載。
- sizeof:一個操作符,以byte為單位返回一個值類型的長度。
- stackalloc:返回在堆上分配的一個記憶體塊的指針。
- struct:是一種值類型,可以聲明常量、欄位、方法、property、索引器、操作符、構造器和內嵌類型。
- throw:拋出一個異常。
- try:異常處理代碼塊的組成部分之一。try代碼塊包括可能會,拋出異常的代碼。參閱catch和finally關鍵字。
- typeof:一個操作符,返回傳入參數的類型。
- unchecked:禁止溢出檢查。
- unsafe:標註包含指針操作的代碼塊、方法或類。
- using:當用於命名空間時,using關鍵字允許訪問該命名空間中的類型,而無需指定其全名。也用於定義finalization操作的範圍。
- virtual:一個方法修飾符,標識可被覆載的方法。
- volatile:標識一個可被操作系統、某些硬體設備或併發線程修改的attribute。
(一)C# 1.0-純粹的面向對象
在2003年5月,微軟推出了Visual Studio .NET 2003,同時也發佈了C#的改進版本——C# 1.1。
這一時期的C#(以下稱為C# 1.x)提出了純粹的面向對象概念。C++並非純面向對象的,為了和C兼容以及提供更高的執行效率,它保留了很多模塊化的東西。C#還通過類類型、值類型和介面類型的概念形成了統一的類型系統。
儘管C# 1.x提供瞭如此多的新鮮概念,但實際上,這些概念都是由CLI提出的。因此當將一個C#源程式編譯為可執行文件時,編譯器做的工作相對而言並不多。需要編譯器代勞的是要將一個簡單的委托定義語句翻譯為一個繼承System.MulticastDelegate類型定義。
(二)C# 2.0-泛型編程新概念
微軟在2004年的6月份發佈了Visual Studio2005的第一個Beta 版,同時向開發者展示了C#語言的2.0版本。2005年4月,微軟發佈了Visual Studio 2005 Beta2,這已經是具備了幾乎全部功能的VisualStudio,包括的產品有SQL Server2005、Team Foundation Server和TeamSuite。這時的C#編譯器已經能夠處理C# 2.0中所有的新特性。
C# 2.0為開發者帶來的最主要的特性就是泛型編程能力。和麵向對象思想一樣,泛型思想也是一種已經成熟的編程思想,但依然是沒有哪一種主流開發語言能夠支持完備的泛型概念。這主要是因為泛型的概念在一定程度上對面向對象概念進行衝擊,同時,由於在編譯期間對類型參數的完全檢測很難做到,很多問題會被遺留到運行時。C# 2.0別出心裁,對泛型類型參數提出了“約束”的新概念,並以優雅的語法體現在語言之中。有了約束,結合編譯器強大的類型推斷能力,可以在編譯時發現幾乎所有“危險”的泛型應用。
C# 2.0的另一個突出的特性就是匿名方法,用來取代一些短小的並且僅出現一次的委托,使得語言結構更加緊湊。匿名方法除了可以使得事件處理器的編寫更加精簡以外,還將開發者帶入了程式設計的一個新的領域——函數式編程,曾經有高人就用匿名方法結合泛型編程實現了函數式編程中的重要結構—— Lambda 表達式。儘管這種實現顯得很繁瑣而且不易理解,但畢竟是實現了。
(三)C#3.0-(研發代號“Orcas”)
2005年9 月份的PDC大會——C#3.0(研發代號“Orcas”——魔鬼)的技術預覽版。說到C# 3.0,就不得不提一下微軟的LINQ 項目,LINQ(語言集成查詢,Language Integrated Query)提出了一種通過面向對象語法來實現對非面向對象數據源的查詢技術,可查詢的數據源從關係型資料庫延伸到一般意義上的集合(如數組和列表)以及XML。而C# 3.0則是率先實現了LINQ的語言。
在C# 3.0中,可以用類似於SQL語句的語法從一個數據源中輕鬆地得到滿足一定條件的對象集合。例如要查找一個字元串數組names中所有長度大於5的字元串,就可以寫:var longname = from n in names wheren.Length > 5 select n;
這樣就得到一個新的字元數組longname,其中包含了所需要的結果。這種語句稱作查詢語句,與SQL語句唯一的區別是C#中的查詢語句往往把select子句放到最後(這反而倒有些類似於中文的閱讀順序了)。初次看到這樣一個語句,可能會有很大疑問:這還是C#語言嗎?這的確是合乎語法規則的C#代碼,而且編譯器可以識別這種語法。然而實際上,C#編譯器並不會對這種語法進行實際的的編譯,而是將其翻譯為正常的方法調用。
(四)C# 4.0動態編程
C# 4.0 新增 dynamic關鍵字,提供動態編程(dynamic programming),把既有的靜態物件標記為動態物件,類似javascript, Python 或 Ruby。
根據育龍網資料評價顯示:C#幾乎集中了所有關於軟體開發和軟體工程研究的最新成果:面向對象、類型安全、組件技術、自動記憶體管理、跨平臺異常處理、版本控制、代碼安全管理……。儘管像很多人註意到的一樣,羅列上述特性時,總是讓人想到JAVA,然而C# 確實走得更遠。但現實的情況是,非技術的因素往往更能決定一個產品的未來,尤其在電腦軟體的歷史上,技術卓越的產品,如OS/2、Mac OS、UNIX等,都敗在了Windows漂亮的界面上。JAVA的用戶主要是網路服務的開發者和嵌入式設備軟體的開發者,嵌入式設備軟體不是C# 的用武之地,而在網路服務方面,C# 的即時編譯和本地代碼Cache方案比JAVA虛擬機具有絕對的性能優勢。何況C# 一旦成為一個像C++ 一樣的公共的標準,軟體開發商既可以省去JAVA的許可證費用,也不必擔心成為微軟的奴隸,那些反微軟的人士和主張廠商獨立的人士可能也不會有什麼意見。這可能正是微軟所期待的。
如果把C# 和 JAVA 在網路服務領域的爭奪比作未來制空權的爭奪,那麼C# 和傳統通用快速開發工具——VB、DELPHI等的較量將是地地道道的白刃戰。可能最慘的程式員就是VB程式員,在微軟,VB就像離任的柯林頓,不但失去了所有的光輝,而且亂事纏身。
其實在編程語言中真正的霸主多年來一直是C++,所有的操作系統和絕大多數的商品軟體都是用C++作為主要開發語言的。JAVA的程式員絕大多數也是C++的愛好者,PHP的成功裡面也有類似C++的語法的功勞。在操作系統、設備驅動程式、視頻游戲等領域,C++在很長的時間內仍將占據主要地位,而在數量最大的應用軟體的開發上,C# 很可能取代C++的位置。首先,C# 和JAVA一樣,簡直就是照搬了C++的部分語法,因此,對於數量眾多的C++程式員學習起來很容易上手,另外,對於新手來說,比C++要簡單一些。其次,Windows是占壟斷地位的平臺,而開發Windows應用,當然微軟的聲音是不能忽略的。最重要的是,相對於C++,用C# 開發應用軟體可以大大縮短開發周期,同時可以利用原來除用戶界面代碼之外的C++代碼。
但是,C# 也有弱點。首先,在一些版本較舊的Windows平臺上,C# 的程式還不能運行,因為C# 程式需要 .NET運行庫作為基礎,而 .NET運行庫作為Windows(XP及以後版本)的一部分發行, Windows Me 和 Windows 2000用戶只能以Service Pack的形式安裝使用。其次,C# 能夠使用的組件或庫還只有 .NET 運行庫等很少的選擇,沒有豐富的第三方軟體庫可用,這需要有一個過程,同時各軟體開發商的支持也很重要。第三,JAVA的成功因素里有一些是反微軟陣營的吹捧,雖然“只寫一次,到處運行”只是一句口號,但畢竟已經是一種成熟的技術。而C# 的鼓吹者只有名聲不佳的微軟,且只能運行在Windows上。實際上這兩種語言都不是不可替代的,理智的說,對軟體開發商而言,什麼用的最熟什麼就是最好的工具。尤其對C++的使用者,C# 沒有帶來任何新東西,因為.NET運行庫在C++中也可以使用,沒有要換的絕對的理由。
C# 將不可避免地崛起,在Windows平臺上成為主角,而JAVA將在UNIX、Linux等平臺上成為霸主,C++ 將繼續在系統軟體領域大展拳腳。非常有意思的是,這些語言的語法極其接近,因為JAVA和C# 都是由C++發展而來的。其他的開發工具當然還會在相當長的時間里繼續他們的旅程,不過在市場份額上,將不可避免地受到衝擊。