Reputation: 7271
I was recently berated for extending a custom class to expose a LINQ extension method on a private member, say:
public virtual T FirstOrDefault(Expression<Func<T, bool>> predicate)
{
return _someDbSet.FirstOrDefault(predicate);
}
Some team members told this is bad. The explanation given was something along the line of: since the inner method is an extension method, the outer should be as well.
(Why) is this so bad?
Upvotes: 1
Views: 200
Reputation: 113332
The explanation given was something along the line of: since the inner method is an extension method, the outer should be as well.
If that was the argument, then that's utter nonsense. Taken to its logical conclusion, we couldn't call any static members in instance members (since extension methods are just static methods with some syntactic sugar to make them look like instance methods on the first argument). Apply that consistently and you'd soon end up with either no static methods at all or no objects at all.
There is a bit of an issue here though:
public virtual T FirstOrDefault(Expression> predicate)
FirstOrDefault
is a commonly used extension method. As such we have an idea what it's going to do whenever we call it.
If the class acts as a collection that wraps _someDbSet
then this method is pointless; we can just use the FirstOrDefault
that already exists.
If the class does not act as a collection that wraps _someDbSet
then this method could be confusing, as it wouldn't act as we'd expect the well-known FirstOrDefault
to act.
If the class is an IEnumerable
or IQueryable
and FirstOrDefault
doesn't do the same thing as the FirstOrDefault
extension method, then it could be very confusing indeed, because the same member name would produce different behaviour depending on how the object was referenced, and that's only very rarely a good thing.
Conversely though, if we had a FirstOrDefault
instance method that did the same thing as FirstOrDefault
would otherwise but did so much more efficiently, then that is a case where having an instance method mask an extension method is a very good thing indeed; there's no behaviour difference as far as the calling code is concerned, just a performance boost that is "free" as far as that calling code goes, as it's written in exactly the same way that it would be anyway.
Upvotes: 0
Reputation: 157058
There isn't a major problem in adding a method with the same name as an existing extension method if it 'overrides' the functionality of that extension method, or the signatures aren't compatible with each other (or if the extension method can't be applied to that specific class).
If those rules don't apply, or you do intent to use both of them, it can be really confusing which method is getting called in the end. This may lead to bugs, so I would not advise to use a method with the same name as the extension method.
Upvotes: 1