Reputation: 5779
I am designing an API that is very comparable to Linq (it's a linq that acts on more complex objects) and I have some client developers who don't quite get the philosophy behind it. I would like to prevent them from doing some things, so that their code is more in line with what the API is all about. So for the examples I will just refer to Linq.
In very short, what I see in the client code is something similar to:
IEnumerable<double> xlist;
IEnumerable<double> ylist;
var zlist = xlist.Select( (x,i) => x + ylist.ElementAt(i) );
This is really bad, and rather than me having to tell people that they are misbehaving, I would like to force my clients to write this instead:
var zlist = xlist.Zip(ylist, (x,y) => x + y);
So after thinking about it, I figured that what I would really want for my API, is to prevent clients from "injecting" data into delegate types. In other words, I would like to define extension methods, such as:
IEnumerable<TResult> MySelect<TSource, TResult>(
this IEnumerable<TSource> source,
StaticFunc<TSource, int, TResult> selector)
where StaticFunc would be some kind of delegate type that doesn't hold any data (or at most that would only static-context data).
Can anyone see a way to do that?
Upvotes: 1
Views: 125
Reputation: 100575
You can try to use Expression Trees instead of delegates. You will be able to check what is passed in to your code unlike in case of delegates.
Upvotes: 0
Reputation: 1503140
I am designing an API that is very comparable to Linq (it's a linq that acts on more complex objects) and I have some client developers who don't quite get the philosophy behind it. I would like to prevent them from doing some things, so that their code is more in line with what the API is all about.
Sounds like what you're really in need of is code review and education, rather than tools. There's certainly nothing within the language to make sure that a developer isn't doing this - and you wouldn't even want to, IMO. For example, your rule would prohibit:
public IQueryable<Person> FindUsersByFirstName(string firstName)
{
return repository.Users.Where(user => user.FirstName == firstName);
}
After all, firstName
is contextual data... but that's perfectly in-keeping with LINQ.
Upvotes: 3