C#移位运算符过载

时间:2011-09-28 17:04:38

标签: c#-4.0 operators

第二个操作数的类型必须是int吗?

...
// 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 * for 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)。

真的原因是代码不清楚了吗?

2 个答案:

答案 0 :(得分:7)

是。这是因为language specification需要它:

  

声明重载的移位运算符时,第一个操作数的类型必须始终是包含运算符声明的类或结构,第二个操作数的类型必须始终为int。

语言设计师没有 做出决定 - 如果想要的话,他们可能会删除该限制 - 但我认为规范的这一部分解释了他们的推理对运算符重载的这个(和其他)限制:

  

虽然用户定义的运算符可以执行任何计算,但是强烈建议不要使用直观预期产生结果的实现。

他们可能希望bitshift运算符总是像bitshift运算符一样运行,而不是完全令人惊讶的事情。

答案 1 :(得分: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" );