Как говорили другие, минимальные / максимальные значения, которые может хранить столбец, и сколько памяти он занимает в байтах, определяется только типом, а не длиной.
Многие из этих ответов говорят о том, что часть (11)
влияет только на ширину отображения, которая не совсем верна, но в основном.
Определение int(2)
без Указанный zerofill будет:
100
100
при выходе (не 0
или 00
) Единственное, что будет делать (2)
, - это также указать нулевое значение :
1
01
. Лучший способ увидеть все нюансы:
CREATE TABLE `mytable` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`int1` int(10) NOT NULL,
`int2` int(3) NOT NULL,
`zerofill1` int(10) ZEROFILL NOT NULL,
`zerofill2` int(3) ZEROFILL NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `mytable`
(`int1`, `int2`, `zerofill1`, `zerofill2`)
VALUES
(10000, 10000, 10000, 10000),
(100, 100, 100, 100);
select * from mytable;
, который будет выводиться:
+----+-------+-------+------------+-----------+
| id | int1 | int2 | zerofill1 | zerofill2 |
+----+-------+-------+------------+-----------+
| 1 | 10000 | 10000 | 0000010000 | 10000 |
| 2 | 100 | 100 | 0000000100 | 100 |
+----+-------+-------+------------+-----------+
Обратите внимание, что столбец int1
имеет гораздо меньшая ширина дисплея, чем zerofill2
, даже если длина больше.
Этот ответ протестирован против MySQL 5.7.12 для Linux и может отличаться или не изменяться для других реализаций.
Эти foreach
для итерации по наборам, которые реализуют IEnumerable
. Это делает это путем вызова GetEnumerator
на наборе, который возвратится Enumerator
.
Этот Перечислитель имеет метод и свойство:
Current
возвраты объект, что Перечислитель в настоящее время включен, MoveNext
обновления Current
к следующему объекту.
понятие индекса является внешним к понятию перечисления и не может быть сделано.
Из-за этого, большинство наборов в состоянии быть пересеченным с помощью индексатора и для конструкции цикла.
я значительно предпочитаю использовать для цикла в этой ситуации по сравнению с отслеживанием индекса с локальной переменной.
Я не полагаю, что существует способ получить значение текущего повторения цикла foreach. Подсчет себя, кажется, лучший способ.
май я спрашиваю, почему Вы хотели бы знать?
кажется, что Вы были бы самый вероятный сделать одну из трех вещей:
1) Получение объекта от набора, но в этом случае у Вас уже есть он.
2) подсчет объектов для более позднего сообщения, обрабатывающего... наборы, имеет свойство Count, которое Вы могли использовать.
3) Установка свойства на основанном на объектах на его порядке в цикле..., хотя Вы могли легко устанавливать это, когда Вы добавили объект к набору.
Если Ваш набор не может возвратить индекс объекта с помощью некоторого метода, единственный путь состоит в том, чтобы использовать счетчик как в Вашем примере.
Однако при работе с индексами, единственный разумный ответ на проблему должен использовать для цикла. Что-либо еще представляет сложность кода, не говоря уже о сложности времени и пространства.
Мог сделать что-то вроде этого:
public static class ForEachExtensions
{
public static void ForEachWithIndex<T>(this IEnumerable<T> enumerable, Action<T, int> handler)
{
int idx = 0;
foreach (T item in enumerable)
handler(item, idx++);
}
}
public class Example
{
public static void Main()
{
string[] values = new[] { "foo", "bar", "baz" };
values.ForEachWithIndex((item, idx) => Console.WriteLine("{0}: {1}", idx, item));
}
}
Это только собирается работать на Список и не любой IEnumerable, но в LINQ существует это:
IList<Object> collection = new List<Object> {
new Object(),
new Object(),
new Object(),
};
foreach (Object o in collection)
{
Console.WriteLine(collection.IndexOf(o));
}
Console.ReadLine();
@Jonathan я не сказал, что это был большой ответ, я просто сказал, что это просто показывало, что было возможно сделать то, что он спросил:)
@Graphain я не ожидал бы, что он будет быстр - я не совсем уверен, как это работает, это могло повторить через весь список каждый раз для нахождения соответствующего объекта, который будет helluvalot, выдерживает сравнение.
Однако Список мог бы сохранить индекс каждого объекта наряду с количеством.
у Jonathan, кажется, есть лучшая идея, если он уточнил бы?
было бы лучше просто провести подсчет того, где Вы готовы в foreach хотя, более просты, и более адаптируемы.
Литеральный Ответ - предупреждение, производительность не может быть столь же хорошей как просто использование int
для отслеживания индекса. По крайней мере, это лучше, чем использование IndexOf
.
просто необходимо использовать перегрузку индексации Выбора для обертывания каждого объекта в набор с анонимным объектом, который знает индекс. Это может быть сделано против чего-либо, что реализует IEnumerable.
System.Collections.IEnumerable collection = Enumerable.Range(100, 10);
foreach (var o in collection.OfType<object>().Select((x, i) => new {x, i}))
{
Console.WriteLine("{0} {1}", o.i, o.x);
}
Я не согласен с комментариями о том, что в большинстве случаев лучше использовать цикл для
.
foreach
- полезная конструкция, и ее нельзя заменить циклом for
ни при каких обстоятельствах.
Например, если у вас есть DataReader и вы просматриваете все записи с помощью foreach
, он автоматически вызывает метод Dispose и закрывает считыватель (который может затем закройте соединение автоматически). Таким образом, это безопаснее, поскольку предотвращает утечку соединения, даже если вы забыли закрыть считыватель.
(Конечно, это хорошая практика - всегда закрывать читатели, но компилятор не поймает это, если вы этого не сделаете - вы не можете гарантировать, что закрыли всех читателей, но вы можете повысить вероятность того, что выиграете »
Вот решение, которое я только что придумал для этой проблемы
Original code:
int index=0;
foreach (var item in enumerable)
{
blah(item, index); // some code that depends on the index
index++;
}
Updated code
enumerable.ForEach((item, index) => blah(item, index));
Extension Method:
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> enumerable, Action<T, int> action)
{
var unit = new Unit(); // unit is a new type from the reactive framework (http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx) to represent a void, since in C# you can't return a void
enumerable.Select((item, i) =>
{
action(item, i);
return unit;
}).ToList();
return pSource;
}
int index;
foreach (Object o in collection)
{
index = collection.indexOf(o);
}
Это будет работать для коллекций, поддерживающих IList
.
Вы можете заключить исходный перечислитель в другой, который действительно содержит информацию об индексе.
foreach (var item in ForEachHelper.WithIndex(collection))
{
Console.Write("Index=" + item.Index);
Console.Write(";Value= " + item.Value);
Console.Write(";IsLast=" + item.IsLast);
Console.WriteLine();
}
Вот код для класса ForEachHelper
.
public static class ForEachHelper
{
public sealed class Item<T>
{
public int Index { get; set; }
public T Value { get; set; }
public bool IsLast { get; set; }
}
public static IEnumerable<Item<T>> WithIndex<T>(IEnumerable<T> enumerable)
{
Item<T> item = null;
foreach (T value in enumerable)
{
Item<T> next = new Item<T>();
next.Index = 0;
next.Value = value;
next.IsLast = false;
if (item != null)
{
next.Index = item.Index + 1;
yield return item;
}
item = next;
}
if (item != null)
{
item.IsLast = true;
yield return item;
}
}
}
Лучше использовать ключевое слово continue
безопасную конструкцию, подобную этой
int i=-1;
foreach (Object o in collection)
{
++i;
//...
continue; //<--- safe to call, index will be increased
//...
}
Вот как я это делаю, что приятно своей простотой / краткостью, но если вы много делаете в теле цикла obj.Value
, это скоро состарится.
foreach(var obj in collection.Select((item, index) => new { Index = index, Value = item }) {
string foo = string.Format("Something[{0}] = {1}", obj.Index, obj.Value);
...
}