Любые шансы подражать временам() Ruby-метод в С#?
Каждый раз, когда мне нужно делать что-то N раз в алгоритме с использованием С#, я пишу этот код
for (int i = 0; i < N; i++)
{
...
}
Изучение Ruby Я узнал о методе times(), который может использоваться с той же семантикой, что и этот
N.times do
...
end
Кодовый фрагмент в С# выглядит более сложным, и мы должны объявить бесполезную переменную i.
Я попытался написать метод расширения, который возвращает IEnumerable, но я не удовлетворен результатом, потому что снова мне нужно объявить циклическую переменную i.
public static class IntExtender
{
public static IEnumerable Times(this int times)
{
for (int i = 0; i < times; i++)
yield return true;
}
}
...
foreach (var i in 5.Times())
{
...
}
Возможно ли использование некоторых новых функций языка С# 3.0, чтобы сделать цикл N более элегантным?
Ответы
Ответ 1
Немного более краткий вариант cvk answer:
public static class Extensions
{
public static void Times(this int count, Action action)
{
for (int i=0; i < count; i++)
{
action();
}
}
public static void Times(this int count, Action<int> action)
{
for (int i=0; i < count; i++)
{
action(i);
}
}
}
Использование:
5.Times(() => Console.WriteLine("Hi"));
5.Times(i => Console.WriteLine("Index: {0}", i));
Ответ 2
Это действительно возможно с С# 3.0:
public interface ILoopIterator
{
void Do(Action action);
void Do(Action<int> action);
}
private class LoopIterator : ILoopIterator
{
private readonly int _start, _end;
public LoopIterator(int count)
{
_start = 0;
_end = count - 1;
}
public LoopIterator(int start, int end)
{
_start = start;
_end = end;
}
public void Do(Action action)
{
for (int i = _start; i <= _end; i++)
{
action();
}
}
public void Do(Action<int> action)
{
for (int i = _start; i <= _end; i++)
{
action(i);
}
}
}
public static ILoopIterator Times(this int count)
{
return new LoopIterator(count);
}
Использование:
int sum = 0;
5.Times().Do( i =>
sum += i
);
Бесстыдно украден из http://grabbagoft.blogspot.com/2007/10/ruby-style-loops-in-c-30.html
Ответ 3
Если вы используете .NET 3.5, вы можете использовать метод расширения. Каждый из предложенных в этой статье и использовать его, чтобы избежать классического цикла.
public static class IEnumerableExtensions
{
public static void Each<T>(
this IEnumerable<T> source,
Action<T> action)
{
foreach(T item in source)
{
action(item);
}
}
}
Этот конкретный метод расширения сваривает каждый метод на все, что реализует IEnumerable. Вы знаете это потому, что первый параметр этот метод определяет, что это будет внутри способ корпус. Действие - это предопределенный класс, который в основном выступает за функцию (делегат) не возвращая никакой ценности. Внутри метода, где элементы извлекаются из списка. Что этот метод Это позволяет мне четко применять функция в одной строке кода.
(http://www.codeproject.com/KB/linq/linq-to-life.aspx)
Надеюсь, что это поможет.
Ответ 4
Я написал собственное расширение, которое добавляет Times to Integer (плюс некоторые другие вещи). Вы можете получить код здесь: https://github.com/Razorclaw/Ext.NET
Код очень похож на ответ Джона Скита:
public static class IntegerExtension
{
public static void Times(this int n, Action<int> action)
{
if (action == null) throw new ArgumentNullException("action");
for (int i = 0; i < n; ++i)
{
action(i);
}
}
}