How to create an extension method overshadowing the regular LINQ extensions?

68 Views Asked by At

I have the following setup, which works as supposed to.

public Thing[] GetThings(Guid id)
  => Context.Things
    .Include(a => a.Members)
    .Where(a => ...).ToArray()
    .SelectArr(a => (Stuff)a with { Related = a.Members.Any(...) });

The special method SelectArr is an extension method because I'm making extensive usage of arrays and making everything an array instead of list or enumerable got tedious.

public static class IEnumerableExtensions
{
  public static T2[] SelectArr<T1, T2>(
    this IEnumerable<T1> self, Func<T1, T2> lambda)
    => self.Select(lambda).ToArray();
}

Then, I tried to overload (shadow, hide etc.) the conventional Select and changed the syntax accordingly. However, switching to it as below wouldn't work.

public Thing[] GetThings(Guid id) => ...
    .Select(a => (Stuff)a with { Related = a.Members.Any(...) });

public static T2[] Select<T1, T2>(
  this IEnumerable<T1> self, Func<T1, T2> lambda) => ...;

Apparently, CS8849, an expression tree may not contain a with-expression. I'm not really sure why nor how to del with it.

I've seen very few relevant hits (like this, not really suggesting an extension method). Most of the results are about how to create an extension method in a general sense, which I already have working. I also found this that creates a whole new object without with. But I'm trying to apply records (hence with) together with the implicit operator (hence the magical cast that, in fact, is a creation in the source object where I can't pass an extra argument).

The best guest I have at the moment is that I don't get into my extension method but, rather, into the conventional one. I can't figure out how to overload/override/new it replacing it with my version. I'm not even sure anymore if I should poke at the projection (i.e. Select(...)) or the filtration (i.e. Where(...)).

I'm also considering skipping the implicit operator and actually creating the new record instance during the projection but that's a bit like giving up.

public static implicit operator Stuff(Thing self) 
  => new(...);

edit

Based on the suggested explanation, I restructured the extension method to target IQueryable like this.

public static class IEnumerableExtensions
{
  //public static T2[] Select<T1, T2>(
  // this IEnumerable<T1> self, Func<T1, T2> lambda)
  // => self.Select(lambda).ToArray();

  public static T2[] Select<T1, T2>(
    this IQueryable<T1> self, Func<T1, T2> lambda)
      => self.AsEnumerable().Select(lambda).ToArray();
}

This produces the error in the invoking method regarding ambiguity. Most importantly, though, it doesn't resolves my main problem, because I'd like to extend on the enumerables not the queryables.

0

There are 0 best solutions below