Перегрузка оператора сдвига в C # - PullRequest
3 голосов
/ 28 сентября 2011

есть ли причина, по которой тип второго операнда должен быть 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...
...

РЕДАКТИРОВАТЬ: Просто точно ... Я могу перегрузить оператор * для получения (например) Список строки

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 ]

7 голосов
/ 28 сентября 2011

Да. Это связано с тем, что спецификация языка требует этого:

При объявлении перегруженного оператора сдвига тип первого операнда всегда должен быть классом или структурой, содержащей объявление оператора, а тип второго операнда всегда должен быть int.

Разработчики языка не имели , чтобы принять это решение - они могли бы снять это ограничение, если бы захотели - но я думаю, что эта часть спецификации объясняет их обоснование для этого (и другие) ограничения на перегрузку операторов:

Хотя пользовательский оператор может выполнять любые вычисления, которые ему нравятся, реализациям, которые дают результаты, отличные от тех, которые ожидаются интуитивно, настоятельно не рекомендуется.

Они, вероятно, хотели, чтобы операторы битового сдвига всегда вели себя как операторы битового сдвига, а не как нечто совершенно удивительное.

0 голосов
/ 28 сентября 2011

Потому что вы хотите, чтобы ваш код выглядел как 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" );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...