Skip to main content
added 208 characters in body
Source Link
t3chb0t
  • 44.7k
  • 9
  • 85
  • 191
linqObject.Where((obj, index) => {
  DoWork(obj, index);
  return true;
}).ToArray();

Never ever! This is the worst possible abuse of an API. I 100% agree with the comment.


int index = 0;
foreach (var item in someEnumerable) {
    DoWork(item, index);
    index++;
}

Yes, this is the way it should be, although this can be shortened... keep reading.


public static void ForEachWithIndex<T>(IEnumerable<T> e, Action<int, T> a)
{
    int index = 0;
    foreach (T v in e) {
        a(index, v);
        index++;
    }
}

This is better but the naming is still quite wrong and the Action parameters are in the wrong order. They should be incremental. This means that T is always there so it should be first, then any other parameters may follow, like the index.


I'm not sure what's wrong with using normal loops where necessary but if you really want to encapsulate them then...


Try to be consistant with the LINQ API and don't invent new method suffixes like WithIndex. Use overloads instead. In fact you can implement it once and call the core method with other overloads.

Notice the order of Action parameters. It's consistant with current APIs. T first then index. There is also no explicit parameter checking because it uses an empty collection if the source is null and the ? operator to not call the delegate if this one is null. You can also throw if you want.

public static class Loop
{
    public static void ForEach<T>(IEnumerable<T> source, Action<T, int> action)
    {
        var i = 0;
        foreach (var item in source ?? Enumerable.Empty<T>()) action?.Invoke(item, i++);
    }
    
    public static void ForEach<T>(IEnumerable<T> source, Action<T> action)
    {
        ForEach(source, (x, i) => action(x));
    }
}
linqObject.Where((obj, index) => {
  DoWork(obj, index);
  return true;
}).ToArray();

Never ever! This is the worst possible abuse of an API. I 100% agree with the comment.


int index = 0;
foreach (var item in someEnumerable) {
    DoWork(item, index);
    index++;
}

Yes, this is the way it should be, although this can be shortened... keep reading.


public static void ForEachWithIndex<T>(IEnumerable<T> e, Action<int, T> a)
{
    int index = 0;
    foreach (T v in e) {
        a(index, v);
        index++;
    }
}

This is better but the naming is still quite wrong and the Action parameters are in the wrong order. They should be incremental. This means that T is always there so it should be first, then any other parameters may follow, like the index.


I'm not sure what's wrong with using normal loops where necessary but if you really want to encapsulate them then...


Try to be consistant with the LINQ API and don't invent new method suffixes like WithIndex. Use overloads instead. In fact you can implement it once and call the core method with other overloads.

Notice the order of Action parameters. It's consistant with current APIs. T first then index.

public static class Loop
{
    public static void ForEach<T>(IEnumerable<T> source, Action<T, int> action)
    {
        var i = 0;
        foreach (var item in source ?? Enumerable.Empty<T>()) action?.Invoke(item, i++);
    }
    
    public static void ForEach<T>(IEnumerable<T> source, Action<T> action)
    {
        ForEach(source, (x, i) => action(x));
    }
}
linqObject.Where((obj, index) => {
  DoWork(obj, index);
  return true;
}).ToArray();

Never ever! This is the worst possible abuse of an API. I 100% agree with the comment.


int index = 0;
foreach (var item in someEnumerable) {
    DoWork(item, index);
    index++;
}

Yes, this is the way it should be, although this can be shortened... keep reading.


public static void ForEachWithIndex<T>(IEnumerable<T> e, Action<int, T> a)
{
    int index = 0;
    foreach (T v in e) {
        a(index, v);
        index++;
    }
}

This is better but the naming is still quite wrong and the Action parameters are in the wrong order. They should be incremental. This means that T is always there so it should be first, then any other parameters may follow, like the index.


I'm not sure what's wrong with using normal loops where necessary but if you really want to encapsulate them then...


Try to be consistant with the LINQ API and don't invent new method suffixes like WithIndex. Use overloads instead. In fact you can implement it once and call the core method with other overloads.

Notice the order of Action parameters. It's consistant with current APIs. T first then index. There is also no explicit parameter checking because it uses an empty collection if the source is null and the ? operator to not call the delegate if this one is null. You can also throw if you want.

public static class Loop
{
    public static void ForEach<T>(IEnumerable<T> source, Action<T, int> action)
    {
        var i = 0;
        foreach (var item in source ?? Enumerable.Empty<T>()) action?.Invoke(item, i++);
    }
    
    public static void ForEach<T>(IEnumerable<T> source, Action<T> action)
    {
        ForEach(source, (x, i) => action(x));
    }
}
Source Link
t3chb0t
  • 44.7k
  • 9
  • 85
  • 191

linqObject.Where((obj, index) => {
  DoWork(obj, index);
  return true;
}).ToArray();

Never ever! This is the worst possible abuse of an API. I 100% agree with the comment.


int index = 0;
foreach (var item in someEnumerable) {
    DoWork(item, index);
    index++;
}

Yes, this is the way it should be, although this can be shortened... keep reading.


public static void ForEachWithIndex<T>(IEnumerable<T> e, Action<int, T> a)
{
    int index = 0;
    foreach (T v in e) {
        a(index, v);
        index++;
    }
}

This is better but the naming is still quite wrong and the Action parameters are in the wrong order. They should be incremental. This means that T is always there so it should be first, then any other parameters may follow, like the index.


I'm not sure what's wrong with using normal loops where necessary but if you really want to encapsulate them then...


Try to be consistant with the LINQ API and don't invent new method suffixes like WithIndex. Use overloads instead. In fact you can implement it once and call the core method with other overloads.

Notice the order of Action parameters. It's consistant with current APIs. T first then index.

public static class Loop
{
    public static void ForEach<T>(IEnumerable<T> source, Action<T, int> action)
    {
        var i = 0;
        foreach (var item in source ?? Enumerable.Empty<T>()) action?.Invoke(item, i++);
    }
    
    public static void ForEach<T>(IEnumerable<T> source, Action<T> action)
    {
        ForEach(source, (x, i) => action(x));
    }
}