I'm trying to make an IEnumerable extension similar to one shown in Using LINQ's Zip with a closure that doesn't return a value by @Hakakou, however I'm trying to modify it to run a method of the first value, with the second value as parameter.
For example:
public class MyObject {
private int myInt;
public MyObject(int a){
myInt = a;
}
public void addToFloat(int b){
myInt += b;
}
}
List<MyObject> objList = new List<ObjList> {new MyObj(5), new MyObj(8)};
List<int> intList = new List<int> {3, 1};
objList.MyExtension(intList, addToFloat)
// Now both MyObjects should have myInt set to 8 and 9 respectively
I'm not however sure how to 'separate' a method from the object and save its signature, then be able to apply it for each object instance with a given value.
If your intention is to create a new linq-style method extension, I think you have to use this code:
static class MyExtensionClass
{
public static IEnumerable<TObj> MyExtension<TObj, TValue>(this IEnumerable<TObj> listObject, IEnumerable<TValue> listValue, Action<TObj, TValue> fun)
{
if (listObjectis null)
throw new ArgumentNullException(nameof(listObject));
if (listValue is null)
throw new ArgumentNullException(nameof(listValue));
if (fun is null)
throw new ArgumentNullException(nameof(fun));
using var enumerator = listValue.GetEnumerator();
foreach (var obj in listObject)
{
if (!enumerator.MoveNext())
fun(obj, enumerator.Current);
yield return obj;
}
}
}
But, there are some warnings:
in fact I have not use the ".Count()" method (for exemple to check if the two list have the same lenght), because in the worst case it will force the evaluation of all item.
Tip: if you are using .NET 6, for the null checks you can use
ArgumentNullException.ThrowIfNull(listObject);
instead of explicit if and throw