StringBuilder (& ldquo; & hellip; & rdquo;). ToString () и новая String () ведут себя по-разному. Зачем? [Дубликат]

В зависимости от вашей конкретной цели существует способ достижения полезности родительского селектора без использования одного (даже если бы он существовал) ...

Скажем, у нас есть:

<div>
  <ul>
    <li><a>Pants</a></li>
    <li><a>Socks</a></li>
    <ul>
      <li><a>White socks</a></li>
      <li><a>Blue socks</a></li>
    </ul>
  </ul>
</div>

Что мы можем сделать, чтобы блок Socks (включая цвета носка) выделялся визуально с использованием интервала?

Что было бы неплохо, но не существует:

ul li ul:parent {
  margin-top: 15px;
  margin-bottom: 15px;
}

Что существует:

li > a {
  margin-top: 15px;
  display: block;
}
li > a:only-child {
  margin-top: 0px;
}

Это устанавливает, что все привязные ссылки имеют верхний край 15px и сбрасывают его обратно на 0 для тех, у которых нет элементов UL (или других тегов) внутри LI.

5
задан wigy 18 September 2010 в 08:04
поделиться

2 ответа

Оператор == не является синонимом, это оператор, который определен для разных типов.

Оператор == определен для строк, а затем он действительно использует Equals method:

public static bool operator ==(string a, string b) {
  return Equals(a, b);
}

Однако в вашем коде вы не используете оператора по строкам, вы используете его на объектах, поэтому вы получаете оператор ==, определенный для объектов, который использует ReferenceEquals, чтобы выполнить сравнение.

Какая перегрузка используемого оператора определяется во время компиляции, поэтому это тип переменных, которые определяют перегрузку, а не фактический тип объектов, которые указывают точки к.

7
ответ дан Guffa 18 August 2018 в 12:35
поделиться
  • 1
    Хммм. Итак, вы говорите, что Object.operator == определяется с помощью ReferenceEquals, тогда как String.operator == определяется с помощью Equals. Разве это не так красиво и интуитивно? – wigy 16 September 2010 в 12:14
  • 2
    @wigy: В большинстве случаев это работает очень хорошо, но, конечно, такие ситуации, как ваш пример, где вы можете ожидать, что сравнение будет определено во время выполнения. Это, конечно, более интуитивно, чем, например, в C ++ и Java, где вы не можете надежно использовать оператор == на строках вообще. В VB оператор = определяет сравнение во время выполнения, что больше соответствует тому, как работает VB, но это дает несколько других ситуаций, когда это может вас удивить. В C # можно определить из кода точно, какое сравнение будет использоваться, что больше соответствует тому, как работает C # в целом. – Guffa 16 September 2010 в 13:10
  • 3
    Спасибо, Гуффа. Я знаю, что это лучше, чем C, Java или VB. Операторы C ++ могут быть виртуальными, поэтому у вас есть разные проблемы. Вот почему большинство стандартов кодирования на C ++ используют условия Yoda, такие как if (5 == something) {...}. Из вашего ответа я понял, что дизайнеры фреймворков считали, что ReferenceEquals более интуитивно понятен для некоторых из кодеров, но с другой стороны фиксированный string.operator ==. – wigy 16 September 2010 в 15:12
  • 4
    Не может ли строка-интернирование сделать, что == также вернет true? Есть предположения? – Ani 18 September 2010 в 08:09
  • 5
    @Ani: Да, если вы сравните две интернированные строки с одинаковым значением, они будут указывать на один и тот же строковый объект. В примере OP строка orange преднамеренно создается во время выполнения, так что она не интернирована. – Guffa 18 September 2010 в 09:22

Операторы определяются как статические методы, поэтому они не могут участвовать в полиморфизме. Таким образом, ваше второе утверждение использует определение == для object (поскольку ваши переменные объявлены как object), который проверяет только ссылочное равенство. Если переменные были объявлены как string, перегрузка == для string была бы использована, и второе утверждение было бы успешным.

6
ответ дан Thomas Levesque 18 August 2018 в 12:35
поделиться
  • 1
    Также стоит отметить, для полноты, что статический object.Equals(apple,orange) вернет true в этом случае. object.Equals сначала использует == для проверки равенства ref, и если это не удается, он будет использовать перегруженный apple.Equals(orange) (предполагая, что apple и orange не null). – LukeH 16 September 2010 в 11:57
  • 2
    Я понимаю, что я использую static bool Object.operator==(Object, Object). Но я до сих пор не понимаю, почему это не называется Object.Equals(Object). Поскольку это виртуально, в конце будет вызываться правильный String.Equals(Object). – wigy 16 September 2010 в 12:10
Другие вопросы по тегам:

Похожие вопросы: