2011-09-28 89 views
2

是否有原因,第二個操作數的類型必須是int?C#移位運算符過載

... 
// I would like to do this 
public static StringList operator<<(StringList list, string s) { 
    list.Add(s); 
    return list; 
} 
// but only int is supported... 
... 

編輯: 就肯定......我能重載operator *的GET(例如)字符串

class MyString { 
    string val; 
    public MyString(string s) { 
     val = s; 
    } 
    public static List<string> operator*(MyString s, int count) { 
     List<string> list = new List<string>(); 
     while (count-- > 0) { 
     list.Add(s.val); 
     } 
     return list; 
    } 
} 

... 
foreach (var s in new MyString("value") * 3) { 
    s.print(); // object extension (Console.WriteLine) 
} 
// output: 
// value 
// value 
// value 
... 

的列表,但不能超載左移,由C衆所周知++ STD(超載爲輸出),因爲它不清楚?當然,這只是C#設計師的決定。 它仍然可以被意想不到的/不明確的(int)重載。

真的是因爲它是一個不明確的代碼?

回答

7

是的。這是因爲該language specification需要它:

當聲明重載移位操作,第一個操作數的類型必須始終是類或包含運算符聲明結構,並且所述第二操作數的類型必須總是int。

語言設計者沒有做出決定 - 這本來是可能爲他們去除這個限制,如果想 - 但我想說明,這部分解釋了他們對這個推理(和操作符重載其他)限制:

儘管有可能爲用戶定義的操作者執行它恣任何計算,產生比那些直觀地預期,強烈建議不要其他結果的實現。

他們可能希望bitshift運算符總是表現得像bitshift運算符一樣,而不是完全令人驚訝的東西。

+3

我要說的卻是C++得到了這個錯誤,C#是正確的。任意運算符重載導致可讀代碼較少。 – tvanfosson

+0

如果bitshift運算符僅在int上有含義,則可能無法重載... –

0

因爲你想讓你的代碼看起來像C++?爲什麼不能使用返回源列表的擴展方法.Append(item)

public static class ListExtensions 
{ 
    public static List<T> Append<T>(this List<T> source, T item) 
    { 
     if (source == null) 
     { 
      throw new NullArgumentException("source"); 
     } 
     source.Add(item); 
     return source; 
    } 
} 

用作:

var list = new List<string>(); 
list.Append("foo") 
    .Append("bar") 
    .Append("baz");