На этот вопрос уже есть ответ здесь:
Вот мой вывод скрипта WIFI info:
из-за этого вопроса, я испытал некоторые вещи придумать хороший синтаксис, не ожидая первоклассной поддержки языка. Вот то, что я имею:
using static Enumerizer;
// prints: 0 1 2 3 4 5 6 7 8 9
foreach (int i in 0 <= i < 10)
Console.Write(i + " ");
Не различие между <=
и <
.
я также создал репозиторий подтверждения концепции на GitHub еще с большей функциональностью (инвертированное повторение, пользовательский размер шага).
А минимальная и очень ограниченная реализация вышеупомянутого цикла посмотрела бы что-то как подобный это:
public readonly struct Enumerizer
{
public static readonly Enumerizer i = default;
public Enumerizer(int start) =>
Start = start;
public readonly int Start;
public static Enumerizer operator <(int start, Enumerizer _) =>
new Enumerizer(start);
public static Enumerizer operator >(int _, Enumerizer __) =>
throw new NotImplementedException();
public static IEnumerable<int> operator <=(Enumerizer start, int end)
{
for (int i = start.Start; i < end; i++)
yield return i;
}
public static IEnumerable<int> operator >=(Enumerizer _, int __) =>
throw new NotImplementedException();
}
По-моему, Enumerable.Range()
путем является больше описания. Новый и незнакомый людям? Конечно. Но я думаю, что этот декларативный подход приводит к тем же преимуществам как большинство других LINQ-связанных функций языка.
Я предполагаю, что могли быть сценарии, где Enumerable.Range(index, count)
более ясно при контакте с выражениями для параметров, особенно если некоторые значения в том выражении изменены в цикле. В случае for
выражение было бы оценено на основе состояния после текущего повторения, тогда как Enumerable.Range()
оценен заранее.
, Кроме которого, я согласился бы, что липкий с for
обычно будет лучше (более знакомый/читаемый большему количеству людей... читаемых, очень важное значение в коде, который должен сохраняться).
Я уверен, что у всех есть их персональные предпочтения (многие предпочли бы позже просто, потому что это знакомо почти по всем языкам программирования), но я похож на Вас и начинающий любить foreach все больше, особенно теперь, когда можно определить диапазон.
@Luke: Я повторно реализовал Ваш To()
дополнительный метод и использовал Enumerable.Range()
метод, чтобы сделать это. Таким образом, это выходит немного короче и использует как можно больше инфраструктуры, данной нам.NET:
public static IEnumerable<int> To(this int from, int to)
{
return from < to
? Enumerable.Range(from, to - from + 1)
: Enumerable.Range(to, from - to + 1).Reverse();
}
Мне отчасти нравится идея. Это очень похоже на Python. Вот моя версия в нескольких строках:
static class Extensions
{
public static IEnumerable<int> To(this int from, int to, int step = 1) {
if (step == 0)
throw new ArgumentOutOfRangeException("step", "step cannot be zero");
// stop if next `step` reaches or oversteps `to`, in either +/- direction
while (!(step > 0 ^ from < to) && from != to) {
yield return from;
from += step;
}
}
}
Это работает как Python:
0.To(4)
в †’ [ 0, 1, 2, 3 ]
4.To(0)
в †’ [ 4, 3, 2, 1 ]
4.To(4)
в †’ [ ]
7.To(-3, -3)
в †’ [ 7, 4, 1, -2 ]
Я думаю foreach + Счетный. Диапазон менее подвержен ошибкам (Вы имеете меньше контроля и меньше способов сделать это неправильно, как уменьшение индекса в теле, таким образом, цикл никогда не заканчивался бы, и т.д.)
, проблема удобочитаемости о семантике функции Диапазона, которая может измениться от одного языка до другого (например, если дали всего один параметр будет он начинаться от 0 или 1, или является концом, включенным или исключенным, или является вторым параметром количество вместо этого значение конца).
О производительности, я думаю, что компилятор должен быть достаточно умным для оптимизации обоих циклов, таким образом, они выполняются на подобной скорости, даже с большими спектрами (я предполагаю, что Диапазон не создает набор, но конечно итератор).
Я думаю, что Диапазон полезен для работы с некоторым встроенным диапазоном:
var squares = Enumerable.Range(1, 7).Select(i => i * i);
Вы можете каждый. Требует, чтобы преобразование перечислило, но сохраняет вещи компактными, когда это - то, что Вы хотите.
Enumerable.Range(1, 7).ToList().ForEach(i => Console.WriteLine(i));
, Но кроме для чего-то вроде этого, я использовал бы традиционный для цикла.
Можно на самом деле сделать это в C# (путем обеспечения To
и Do
как дополнительные методы на int
и IEnumerable<T>
соответственно):
1.To(7).Do(Console.WriteLine);
SmallTalk навсегда!
В C# 6.0 с использованием
using static System.Linq.Enumerable;
можно упростить его до
foreach (var index in Range(1, 7))
{
Console.WriteLine(index);
}
Это только для забавы. (Я просто использовал бы стандарт" for (int i = 1; i <= 10; i++)
" формат цикла сам.)
foreach (int i in 1.To(10))
{
Console.WriteLine(i); // 1,2,3,4,5,6,7,8,9,10
}
// ...
public static IEnumerable<int> To(this int from, int to)
{
if (from < to)
{
while (from <= to)
{
yield return from++;
}
}
else
{
while (from >= to)
{
yield return from--;
}
}
}
Вы могли также добавить Step
дополнительный метод также:
foreach (int i in 5.To(-9).Step(2))
{
Console.WriteLine(i); // 5,3,1,-1,-3,-5,-7,-9
}
// ...
public static IEnumerable<T> Step<T>(this IEnumerable<T> source, int step)
{
if (step == 0)
{
throw new ArgumentOutOfRangeException("step", "Param cannot be zero.");
}
return source.Where((x, i) => (i % step) == 0);
}
Я хотел бы иметь синтаксис некоторых других языков как Python, Haskell, и т.д.
// Write the numbers 1 thru 7
foreach (int index in [1..7])
{
Console.WriteLine(index);
}
Fortunatly, мы получили F# теперь :)
Что касается C#, я должен буду придерживаться с Enumerable.Range
метод.
Как ответы в этом предлагает сообщение , два главных вида переключателей уничтожения обрабатывают действие любого радио Wi-Fi - твердый / аппаратный переключатель и мягкий переключатель / переключатель программного обеспечения.
опции Several доступны для включения переключателя программного обеспечения, тот, который использует rfkill, мог бы быть самым полезным из них всех. Запустите терминал "Ctrl+Alt+T" и выполнением в следующем коде (тип в пароле для корня, если спросили относительно):
sudo rfkill unblock all
, Так как Ваш журнал ошибок показывает, что твердый переключатель не является проблемой, но все еще в отсутствие никакого видимого аппаратного переключателя (обычно кнопка), Вы могли попробовать грязный старый прием. Просто удалите батарею из случая Вашего компьютера в течение нескольких минут, откройте крышку, если Вы уже не имеете, как будто необходимо было запустить компьютер без батареи, потребовать у кнопки питания в течение нескольких секунд (обычно, 30 секунд сделали бы). Затем повторно вставьте батарею и включите свой компьютер. Посмотрите, разрешена ли проблема.