2010-04-06 130 views
7

天兒真好配合 -C#字符串運算符重載

什麼是正確的方式(不包括它是否是可取的說法)超載字符串運算<,>,< =和> =?

我試過五種方法到星期天,我得到各種錯誤 - 我最好的辦法是聲明一個部分類和從那裏重載,但它不會因爲某些原因。

namespace System 
{ 
    public partial class String 
    { 
     public static Boolean operator <(String a, String b) 
     { 
      return a.CompareTo(b) < 0; 
     } 

     public static Boolean operator >(String a, String b) 
     { 
      return a.CompareTo(b) > 0; 
     } 
    } 

}

+0

FYI:部分類需要駐留在同一組件(項目)。 – 2014-04-03 06:34:17

+0

這些運算符已經定義了字符串,因此重新定義它們是沒有意義的。如果可能的話,它可能會破壞很多代碼。 – Phil1970 2016-06-03 23:00:29

回答

16

字符串是一個密封的類。您不能繼承它,並且沒有String的原始源,您無法編譯它的部分類。即使你已經掌握了源代碼(可以通過Reflector或通過Visual Studio符號下載),你仍然會遇到問題,因爲它是運行時的頭等公民。

你真的需要<和>作爲字符串運算符嗎?如果是這樣......爲什麼不使用extension methods

public static bool IsLessThan(this string a, string b) 
{ 
    return a.CompareTo(b) < 0; 
} 

public static bool IsGreaterThan(this string a, string b) 
{ 
    return a.CompareTo(b) > 0; 
} 


// elsewhere... 
foo.IsLessThan(bar); // equivalent to foo < bar 
+4

即使他能繼承它,只知道是他繼承型**的和繼承的類型引用的情況下**將能夠使用備用的運營商。由於運算符不是多態的(它們被重載,沒有被覆蓋),即使將子類型引用爲「字符串」也會消除替代運算符的功能。 – 2010-04-06 19:27:14

+0

@亞當羅賓遜:確切地說。底線:@ScottSEA根本無法做他想做的事。 – Randolpho 2010-04-06 19:34:14

+1

我知道你的帖子不是關於擴展方法,但它可能是有用的提供一個鏈接。對於新來的C#人來說,它看起來像被稱爲錯誤的。 http://msdn.microsoft.com/en-ca/library/vstudio/bb383977.aspx – jgreep 2013-01-15 17:46:44

5

你的意思是System.String類?這在C#中是不可能的。您不能將擴展操作符添加到現有的類。這是一個很多要求功能,但。

10

簡單的答案是,你不能;沒有辦法爲另一個班級修改操作員。部分類只允許在同一程序集中定義的所有文件和中聲明的聲明爲partial

3
  • 你不能有串部分類,因爲String類本身不部分,因此不會與你的部分類的工作。

  • 字符串是密封的,所以你可以繼承它,然後重載操作符。

總之,唉,你不能做你做的事情。

不知道你想要做什麼,我不能建議一個好的選擇。但是,看看extension methods,這往往是有利於情況。撇開無論你是否應該 :),你可以添加到字符串類的方法稱爲IsGreaterThan並返回true或false,但是你希望。這是很好的,因爲您可以給擴展方法一個名稱,使其意義明確,使現有的操作符保持完整(無論如何您都沒有選擇),並且允許快速/簡單的代碼。

1

您不能直接重載> =和< =運算符,但可以通過分別重載>和==來實現相同的結果。

你的代碼似乎對我來說是正確的,只是你錯過了==的重載。

似乎我錯了,但是,你總是可以回到反思。我認爲如果你做一些挖掘和黑客攻擊,你可以使用反射來擴展類,因爲反射允許在運行時添加函數或交換函數體。

無論是可取的,好的做法,我表示懷疑。爲什麼課堂被封閉是有原因的。做一些我提到的事情可能會導致某些情況下的未定義行爲,這是由於.net框架對字符串所做的一些假設。機會很大,字符串類將在內部崩潰。

+1

因爲練習不好而陷入困境? :p – Henri 2010-04-06 19:29:23

15

沒有辦法更換任何內建有自己的編譯器的行爲。您無法覆蓋現有的內置運算符以進行比較,轉換,算術運算等等。這是設計的;這是爲了讓別人可以讀取你的代碼,並知道int x = M(); int y = x + 2;做整數算術,而不是格式化你的硬盤。

你能解釋一下你爲什麼要這麼做?也許有更好的方法去做你想做的事。

+0

感謝您的回答。作爲一個敏銳的堅持的設計決定,它可以解釋爲什麼自定義字符串運算符在十年前不可能實現,而且至今還沒有。 – 2013-09-29 14:42:39

+0

我要尋找的,而代表 'String.Concat(Enumerable.Repeat( 「你好」,4))' 作爲 ' 「你好」 * 4' 是否有人知道這是可能的以任何方式? – 2016-08-29 15:51:09

+1

@AlexeyKhoroshikh:不。沒有可以定義該運算符的類型。 – 2016-08-29 15:58:49