В ответ на Is there a specific reason?
здесь представлено одно интересное приложение: разрыв нескольких уровней цикла.
Вот как это работает: внешний контур имеет разрыв в конце, поэтому он будет выполняется только один раз. Однако, если внутренний цикл завершает (не находит делителя), он достигает выражения else, и внешний разрыв никогда не достигается. Таким образом, разрыв во внутреннем цикле будет выходить из обеих петель, а не только из одного.
for k in [2, 3, 5, 7, 11, 13, 17, 25]:
for m in range(2, 10):
if k == m:
continue
print 'trying %s %% %s' % (k, m)
if k % m == 0:
print 'found a divisor: %d %% %d; breaking out of loop' % (k, m)
break
else:
continue
print 'breaking another level of loop'
break
else:
print 'no divisor could be found!'
Для циклов while
и for
оператор else
выполняется в конец, если не было использовано break
.
В большинстве случаев есть лучшие способы сделать это (обертывание его в функцию или создание исключения), но это работает!
Вам нужно реализовать IEquatable
или переопределить Equals()
и GetHashCode()
Например:
public class CartProduct : IEquatable<CartProduct>
{
public Int32 ID;
public String Name;
public Int32 Number;
public Decimal CurrentPrice;
public CartProduct(Int32 ID, String Name, Int32 Number, Decimal CurrentPrice)
{
this.ID = ID;
this.Name = Name;
this.Number = Number;
this.CurrentPrice = CurrentPrice;
}
public String ToString()
{
return Name;
}
public bool Equals( CartProduct other )
{
// Would still want to check for null etc. first.
return this.ID == other.ID &&
this.Name == other.Name &&
this.Number == other.Number &&
this.CurrentPrice == other.CurrentPrice;
}
}
Если вы хотите иметь контроль над этим, вам нужно реализовать [IEquatable interface] [1]
[1]: http: // Этот метод определяет равенство по используя сопоставитель равенства по умолчанию, как определено реализацией объекта метода IEquatable.Equals для T (тип значений в списке).
Он проверяет, содержится ли конкретный объект в списке.
Возможно, вам лучше использовать метод Find в списке.
Вот пример
List<CartProduct> lst = new List<CartProduct>();
CartProduct objBeer;
objBeer = lst.Find(x => (x.Name == "Beer"));
Надеюсь, что поможет
Вы также должны посмотреть на LinQ - overkill для этого, возможно, но полезный инструмент, тем не менее ...
Equals()
был изменен по любой причине)
– Rowland Shaw
13 April 2010 в 16:18
Если вы используете .NET 3.5 или новее, вы можете использовать методы расширения LINQ для достижения проверки «содержит» с помощью метода расширения Any
:
if(CartProducts.Any(prod => prod.ID == p.ID))
Это проверит наличие продукта внутри CartProducts
, который имеет идентификатор, соответствующий ID p
. Вы можете поместить любое логическое выражение после =>
для выполнения проверки.
Это также имеет преимущество для работы с запросами LINQ-SQL, а также с запросами в памяти, где Contains
нет.
По умолчанию ссылочные типы имеют ссылочное равенство (т. е. два экземпляра равны только, если они являются одним и тем же объектом).
Вам необходимо переопределить Object.Equals
(и Object.GetHashCode
для соответствия), чтобы реализовать ваши собственное равенство. (И тогда хорошей практикой является реализация равенства, ==
, operator.)
CartProduct
объектов велось по-разному в разных местах.
– Rowland Shaw
13 April 2010 в 12:51
Contains()
». Согласитесь, что Find()
может решить проблему, хотя я бы предположил, что подходящий метод equals может быть более полезным в нагрузках других случаев, поскольку OP не заметил, что ссылки для двух экземпляров одного и того же объекта были разными.
– Rowland Shaw
13 April 2010 в 13:06