Which extension methode will be used? - c#

I cannot explain for myself which extension method matches the current MS API documentation, look at the screenshots.
There's an IEnumerable.ToDictionary method used with 3 parameters FUNC key, FUNC Value, FUNC comparer, in this order:
But within the MS API Doc IEnumerable extension methods
there seems no matching definition for the method above (key, value, comparer).
Who can explain this?

The comparer isn't a "FUNC" - it's a new NonUniqueComparer(), which I'm guessing is a type which implements IEqualityComparer<T>.
Intellisense tells you that it's chosen the (Func<TSource, TKey> keySelector, Func<TSource, TElement> elementSelector, IEqualityComparer<TKey> comparer) overload (where TSource is 'a, TKey is object, and TElement is object), which is the bottom one in your screenshot.

Related

Entity Framework - Expression vs Func

Consider this 2 codes:
Using Func<T, bool>
public IQueryable<Blog> GetBlogs(Func<Blog, bool> predicate)
{
return context.Blogs.Where(predicate).AsQueryable();
}
Using Expression<Func<T, bool>>
public IQueryable<Blog> GetBlogs(Expression<Func<Blog, bool>> predicate)
{
return context.Blogs.Where(predicate); // No need of AsQueryable
}
So, in the first case, the Entity Framework will always returns all objects from the database, right? So what's the point in calling AsQueryable? Does it help anyway? It´s similar to the Expression version?
Does it help anyway?
No.
All it does is lie to the caller of the method, in that they think that they have an IQueryable that will translate any additional operators applied to it to SQL run in the database, when in fact you just have an IEnumerable in sheep's clothing. If you really want the operation to be performed in-memory, and not in the DB, then at least be explicit about it an leave the IEnumerable typed as an IEnumerable.

Do interfaces not care about the name of the method when using Lambda expressions?

I guess I am a little confused by a couple of lines of code I have seen.
The first one:
IEnumerable<SignalViewModel> SelectionQuery =
from SignalViewModel svm in AvailableSignalsListView.SelectedItems
orderby AvailableSignalsListView.Items.IndexOf(svm)
select svm;
_GraphViewerViewModel.SelectAvailableSignals(SelectionQuery);
makes sense to me because the orderby defined here:
http://msdn.microsoft.com/en-us/library/bb534966%28v=vs.110%29.aspx
takes a source and a key selector. I am guessing that the query portion
orderby AvailableSignalsListView.Items.IndexOf(svm) creates a lambda expression and calls
Enumerable.OrderBy<TSource, TKey> Method (IEnumerable<TSource>, Func<TSource, TKey>)
with the IEnumerable<TSource> being AvailableSignalsListView.SelectedItems
and the Func<TSource, TKey> being a lambda expression created from the query statement along the lines of
svm => AvailableSignalsListView.Items.IndexOf(svm);
This one makes sense to me though i'm uncertain if my understanding of the details is correct.
The second one,
List<SignalViewModel> mySelectedItems = new List<SignalViewModel>();
//sort version
foreach (SignalViewModel svm in AvailableSignalsListView.SelectedItems)
{
mySelectedItems.Add(svm);
}
mySelectedItems.Sort((x,y) => AvailableSignalsListView.Items.IndexOf(x).CompareTo(AvailableSignalsListView.Items.IndexOf(y)));
doesn't make sense because sort takes an icomparer. I can accept that an icomparer only needs a function as defined by its interface (that takes two items and returns an int). However, how does the computer know what function name to give the delegate behind the scenes? or do interfaces not actually care about the names of functions?
There are several overloads to List.Sort. One that takes an IComparer interface, and one that takes a Comparison delegate. This is using the latter.
If you had a method that only accepted an interface you couldn't pass in a delegate; that wouldn't work.

Create method with unlimited expression parameters?

I have created a repository method with the following signature:
T Get<TProperty>(int id, Expression<Func<T, TProperty>> include)
This works fine but I would like to extend it to take in an unlimited number of includes. I cannot simply use params because each include will return a different TProperty.
Is there a nice way around this or do I have to create several overloads for 1, 2 or 3 includes for example?
If the TProperty types can be different, and if you want to make them different types, then you'd need several overloads.
T Get<TProperty>(int id, Expression<Func<T, TProperty>> include) { ... }
T Get<TProperty1, TProperty2>(int id, Expression<Func<T, TProperty1>> include1, Expression<Func<T, TProperty2>> include2)
OR you could use:
T Get(int id, params Expression<Func<T, object>>[] includes)
And rely on the covariance of the Func generic delegate, but then you'd have to handle the fact you're losing a bit of type safety.
Because Func is covariance on the return type, this means that if your delegate expects a return of object, you can still pass it a delegate with a narrower return type (though warning, with covariance value types aren't covariantly compatible with object, only reference types).
The code you have posted won't allow you to return a different TProperty but only the type you will specify at runtime as <TProperty>
You could use Params and use Object instead of the generic type

invoking a static method with an instance of the class. why?

This is a small snippet of code that I found.
when we make a call
object.Max(s=>s.Length)
why do we need a static method?
public static TResult Max<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, TResult> selector)
{
return source.Select(selector).Max();
}
please update the question title. I couldnot abstract it well.
That is an extension method (via the this modifier on the first parameter). The obj. is passed in as the first argument instead. So:
obj.Max()
is identical to:
DeclaringType.Max(obj, s=>s.Length)
But note that genuine instance methods always take precedence during static analysis, so if the object had a suitable Max method itself, it would be chosen instead of the extension method.
Extension methods must be static methods on non-nested static classes.

Why Func<T,bool> instead of Predicate<T>?

This is just a curiosity question I was wondering if anyone had a good answer to:
In the .NET Framework Class Library we have for example these two methods:
public static IQueryable<TSource> Where<TSource>(
this IQueryable<TSource> source,
Expression<Func<TSource, bool>> predicate
)
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
Why do they use Func<TSource, bool> instead of Predicate<TSource>? Seems like the Predicate<TSource> is only used by List<T> and Array<T>, while Func<TSource, bool> is used by pretty much all Queryable and Enumerable methods and extension methods... what's up with that?
While Predicate has been introduced at the same time that List<T> and Array<T>, in .net 2.0, the different Func and Action variants come from .net 3.5.
So those Func predicates are used mainly for consistency in the LINQ operators. As of .net 3.5, about using Func<T> and Action<T> the guideline states:
Do use the new LINQ types Func<> and
Expression<> instead of custom
delegates and predicates
I've wondered this before. I like the Predicate<T> delegate - it's nice and descriptive. However, you need to consider the overloads of Where:
Where<T>(IEnumerable<T>, Func<T, bool>)
Where<T>(IEnumerable<T>, Func<T, int, bool>)
That allows you to filter based on the index of the entry as well. That's nice and consistent, whereas:
Where<T>(IEnumerable<T>, Predicate<T>)
Where<T>(IEnumerable<T>, Func<T, int, bool>)
wouldn't be.
Surely the actual reason for using Func instead of a specific delegate is that C# treats separately declared delegates as totally different types.
Even though Func<int, bool> and Predicate<int> both have identical argument and return types, they are not assignment-compatible. So if every library declared its own delegate type for each delegate pattern, those libraries would not be able to interoperate unless the user inserts "bridging" delegates to perform conversions.
// declare two delegate types, completely identical but different names:
public delegate void ExceptionHandler1(Exception x);
public delegate void ExceptionHandler2(Exception x);
// a method that is compatible with either of them:
public static void MyExceptionHandler(Exception x)
{
Console.WriteLine(x.Message);
}
static void Main(string[] args)
{
// can assign any method having the right pattern
ExceptionHandler1 x1 = MyExceptionHandler;
// and yet cannot assign a delegate with identical declaration!
ExceptionHandler2 x2 = x1; // error at compile time
}
By encouraging everyone to use Func, Microsoft is hoping that this will alleviate the problem of incompatible delegate types. Everyone's delegates will play nicely together, because they will just be matched up based on their parameter/return types.
It doesn't solve all problems, because Func (and Action) can't have out or ref parameters, but those are less commonly used.
Update: in the comments Svish says:
Still, switching a parameter type from
Func to Predicate and
back, doesn't seem to make any
difference? At least it still compiles
without any problems.
Yes, as long as your program only assigns methods to delegates, as in the first line of my Main function. The compiler silently generates code to new a delegate object that forwards on to the method. So in my Main function, I could change x1 to be of type ExceptionHandler2 without causing a problem.
However, on the second line I try to assign the first delegate to another delegate. Even thought that 2nd delegate type has exactly the same parameter and return types, the compiler gives error CS0029: Cannot implicitly convert type 'ExceptionHandler1' to 'ExceptionHandler2'.
Maybe this will make it clearer:
public static bool IsNegative(int x)
{
return x < 0;
}
static void Main(string[] args)
{
Predicate<int> p = IsNegative;
Func<int, bool> f = IsNegative;
p = f; // Not allowed
}
My method IsNegative is a perfectly good thing to assign to the p and f variables, as long as I do so directly. But then I can't assign one of those variables to the other.
The advice (in 3.5 and above) is to use the Action<...> and Func<...> - for the "why?" - one advantage is that "Predicate<T>" is only meaningful if you know what "predicate" means - otherwise you need to look at object-browser (etc) to find the signatute.
Conversely Func<T,bool> follows a standard pattern; I can immediately tell that this is a function that takes a T and returns a bool - don't need to understand any terminology - just apply my truth test.
For "predicate" this might have been OK, but I appreciate the attempt to standardise. It also allows a lot of parity with the related methods in that area.

Categories