Getting results from each method within a delegate - c#

I'm using a delegate to hold a few methods that test a value and return a true/false result. After learning that a call to a delegate will only return the result of the last method in the delegate, I'm unsure of how to proceed.
I'd like to receive either the list of results from all the method calls in a delegate or if any of the calls returned true.
First I tried enumerating over the delegate with a foreach, which didn't work. I had to pull the methods out beforehand like so
System.Delegate[] methods = int_testers.GetInvocationList();
// Methods in int_testers returns true when a condition is met by the input value
Then enumerate with dynamic invokes on each member within 'methods'
foreach (var item in ds) {
if ((bool)item.DynamicInvoke(4))
return true;
}
However, I've read that DynamicInvoke is much slower (order of magnitude or more) than Invoke which is a trade off I'm not willing to make.
The alternative so far I've found is to have a list of Func<int,bool> and enumerate over those,
List<Func<int,bool>> methods = ....; // Add the methods into the list
foreach (var method in methods) {
if(method(4)) {
return true;
}
}
While this works, it seems like an issue delegates were made to solve. So, finally, is there a way to get a list of results from a delegate without simulating a delegate by hand?
This is essentially using the results of a map function in functional terms but I don't have enough C# experience to bring that idea nicely to what I'm doing.
I looked into LINQ a little for this and it seems it could work with the second method I've outlined though I can't seem to use LINQ with delegates in this case.

You could use Predicate<T> instead of delegate, and LINQ's Any() instead of a for loop:
var methods = new List<Predicate<T>>();
// add methods to list
return methods.Any(x => x(4));

Related

Return true called inside LINQ Select statement

I ran across some code in an older project I am working on that I've never seen before, and has me confused on it's intent.
updatables.Select(r =>
{
// some operations are done here for each element in the list
return true;
}).ToArray();
It seems like a select statement is being used to iterate the updatables collection. Also seems the ToArray call isn't doing anything.
My question is, what does calling return true in the Select statement accomplish, if anything?
This looks very much like a hack to emulate ForEach:
ToArray() call is added to ensure that updatables will be iterated to completion,
return true is added to silence the compiler that does not allow Action<T>, but allows Func<T,bool> in LINQ's Select.
I would strongly recommend against writing code like this, because it is a lot less readable than an equivalent foreach loop.
Select takes a Func<T, TResult> - which means it won't accept an Action<T>. In other words, a lambda which does not return anything will result in a compilation error when passed to Select, so the author bypassed that "limitation" by having it return a dummy value.
The intent behind this code is likely to run a foreach loop on the collection using the LINQ syntax. However, the way it's done in this code is a bad practice, as LINQ methods are expected to be pure - that is, not modify any sort of state outside of the expression.

Getting the results of distinct( IEqualityComparer comparer)

As a LINQ-beginner I wonder why nobody mentioned in Implementing IEqualityComparer<T> for comparing arbitrary properties of any class (including anonymous) that the query actually has to be carried out to get the results. In other words, just calling
IEnumerable<Person> people = ... ; // some database call here
var distinctPeople = people.Distinct(new PropertyComparer<Person>("FirstName"));
will not trigger the execution of the specific Equals(Tx, Ty) and GetHashCode(T obj) methods in the PropertyComparer.
The message "Expanding the Results View will enumerate the IEnumerable" (in the Debugger) gave me the hint. Now, could I proceed with something like foreach (var dp in distinctPeople) to get the results?
This has nothing at all to do with the IEqualityComparer. It is entirely based on the method you're providing it to, in this case, Distinct. Distinct, along with all of the LINQ methods that return an IEnumerable, defer execution as much as possible, only performing the work that they need to compute the results when they actually need to do so.

How to use existing method instead of lambda when it's not static?

This must be a duplicate but i haven't found it. I've found this question which is related since it answers why it's recommended to use a method group instead of a lambda.
But how do i use an existing method group instead of a lambda if the method is not in the current class and the method is not static?
Say i have a list of ints which i want to convert to strings, i can use List.ConvertAll, but i need to pass a Converter<int, string> to it:
List<int> ints = new List<int> { 1 };
List<string> strings = ints.ConvertAll<string>(i => i.ToString());
This works, but it creates an unnecessary anonymous method with the lambda. So if Int32.ToString would be static and would take an int i could write:
List<string> strings = ints.ConvertAll<string>(Int32.ToString);
But that doesn't compile - of course. So how can i use a method group anyway?
If i'd create an instance method like this
string FooInt(int foo)
{
return foo.ToString();
}
i could use strings = ints.ConvertAll<string>(FooInt);, but that is not what i want. I don't want to create a new method just to be able to use an existing.
There is an static method in the framework, that can be used to convert any integrated data type into a string, namely Convert.ToString:
List<int> ints = new List<int> { 1 };
List<string> strings = ints.ConvertAll<string>(Convert.ToString);
Since the signature of Convert.ToString is also known, you can even eliminate the explicit target type parameter:
var strings = ints.ConvertAll(Convert.ToString);
This works. However, I'd also prefer the lambda-expression, even if ReSharper tells you something different. ReSharper sometimes optimizes too much imho. It prevents developers from thinking about their code, especially in the aspect of readability.
Update
Based on Tim's comment, I will try to explain the difference between lambda and static method group calls in this particular case. Therefor, I first took a look into the mscorlib disassembly to figure out, how int-to-string conversion exactly works. The Int32.ToString method calls an external method within the Number-class of the System namespace:
[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), SecuritySafeCritical]
public string ToString(IFormatProvider provider)
{
return Number.FormatInt32(this, null, NumberFormatInfo.GetInstance(provider));
}
The static Convert.ToString member does nothing else than calling ToString on the parameter:
[__DynamicallyInvokable]
public static string ToString(int value)
{
return value.ToString(CultureInfo.CurrentCulture);
}
Technically there would be no difference, if you'd write your own static member or extension, like you did in your question. So what's the difference between those two lines?
ints.ConvertAll<string>(i => i.ToString());
ints.ConvertAll(Convert.ToString);
Also - technically - there is no difference. The first example create's an anonymous method, that returns a string and accepts an integer. Using the integer's instance, it calls it's member ToString. The second one does the same, with the exception that the method is not anonymous, but an integrated member of the framework.
The only difference is that the second line is shorter and saves the compiler a few operations.
But why can't you call the non-static ToString directly?
Let's take a look into the ConvertAll-method of List:
public List<TOutput> ConvertAll<TOutput>(Converter<T, TOutput> converter)
{
if (converter == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.converter);
}
List<TOutput> list = new List<TOutput>(this._size);
for (int i = 0; i < this._size; i++)
{
list._items[i] = converter(this._items[i]);
}
list._size = this._size;
return list;
}
The list iteraterates over each item, calls the converter with the item as an argument and copys the result into a new list which it returns in the end.
So the only relation here is your converter that get's called explicitly. If you could pass Int32.ToString to the method, the compiler would have to decide to call this._items[i].ToString() within the loop. In this specific case it would work, but that's "too much intelligence" for the compiler. The type system does not support such code conversions. Instead the converter is an object, describing a method that can be called from the scope of the callee. Either this is an existing static method, like Convert.ToString, or an anonymous expression, like your lambda.
What causes the differences in your benchmark results?
That's hard to guess. I can imagine two factors:
Evaluating lambdas may result in runtime-overhead.
Framework calls may be optimized.
The last point especially means, that the JITer is able to inline the call which results in a better performance. However, those are just assumptions of mine. If anyone could clarify this, I'd appreciate it! :)
You hit the nail on the head yourself:
This works, but it creates an unnecessary anonymous method with the
lambda.
You can't do what you're asking for because there is no appropriate method group that you can use so the anonymous method is necessary. It works in that other case because the implicit range variable is passed to the delegate created by the method group. In your case, you need the method to be called on the range variable. It's a completely different scenario.

Invoking a method of the key object of a dictionary using lambda expressions

If I have something like:
Dictionary<SomeObject, SomeOtherObject> _mydictionary
and SomeObject has a method: SomeMethod()
How do I call the method SomeMethod() using lambda expressions without converting the keys to a list and doing a ForEach. The ToList() makes it too expensive. Or, the equivalent in lambda to:
foreach(SomeObject o in _mydictionary.Keys)
o.SomeMethod();
???
I tried:
_mydictionary.ToList().ForEach(x => x.SomeMethod());
but this seems too expensive with the ToList();
Use the Reactive Extensions (Rx):
var keys = _mydictionary.Keys;
// convert the enumerable sequence of keys to an observable sequence
var observableKeys = keys.ToObservable ();
// invoke SomeMethod for each key
await observableKeys.ForEachAsync (obj =>
obj.SomeMethod ());
This code will execute without blocking calls enumerating the sequence prior to calling the 1st SomeMethod, and it won't allocate another collection.
Unfortunately we're waiting for a new release of the Interactive Extensions (Ix) that would have exactly the same functionality without the need to convert from an enumerable to an observable sequence.
There is no built-in extension method to invoke a collection of void methods, whether delegates or members of a collection of objects.
You can, however, create one relatively easily:
public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)
{
foreach (var item in items) action(item);
}
Now you can call all those methods in a LINQish way:
_mydictionary.Keys.ForEach(x => x.SomeMethod());
You already have access to the .Keys collection property on IDictionary<TKey,TValue>; you don't need to call .ToList() anywhere.
If SomeMethod() is a function, and you want to create a result set, then you can use the built-in extension method Select():
var results = _mydictionary.Keys.Select(x => x.SomeMethod());
As George rightly points out, SomeMethod() will not be invoked unless needed -- that is, unless you actually use the results by iterating over them. This can avoid the overhead of creating a new collection, but one should take care to avoid multiple enumerations.

Caching delegate results

I have a C# method which accepts a Predicate<Foo> and returns a list of matching items...
public static List<Foo> FindAll( Predicate<Foo> filter )
{
...
}
The filter will often be one of a common set...
public static class FooPredicates
{
public static readonly Predicate<Foo> IsEligible = ( foo => ...)
...
}
...but may be an anonymous delegate.
I'd now like to have this method cache its results in the ASP.NET cache, so repeated calls with the same delegate just return the cached result. For this, I need to create a cache key from the delegate. Will Delegate.GetHashCode() produce sensible results for this purpose? Is there some other member of Delegate that I should look at? Would you do this another way entirely?
To perform your caching task, you can follow the other suggestions and create a Dictionary<Predicate<Foo>,List<Foo>> (static for global, or member field otherwise) that caches the results. Before actually executing the Predicate<Foo>, you would need to check if the result already exists in the dictionary.
The general name for this deterministic function caching is called Memoization - and its awesome :)
Ever since C# 3.0 added lambda's and the swag of Func/Action delegates, adding Memoization to C# is quite easy.
Wes Dyer has a great post that brings the concept to C# with some great examples.
If you want me to show you how to do this, let me know...otherwise, Wes' post should be adequate.
In answer to your query about delegate hash codes. If two delegates are the same, d1.GetHashCode() should equal d2.GetHashCode(), but I'm not 100% about this. You can check this quickly by giving Memoization a go, and adding a WriteLine into your FindAll method. If this ends up not being true, another option is to use Linq.Expression<Predicate<Foo>> as a parameter. If the expressions are not closures, then expressions that do the same thing should be equal.
Let me know how this goes, I'm interested to know the answer about delegate.Equals.
Delegate equality looks at each invocation in the invocation list, testing for equality of method to be invoked, and target of method.
The method is a simple piece of the cache key, but the target of the method (the instance to call it on - assuming an instance method) could be impossible to cache in a serializable way. In particular, for anonymous functions which capture state, it will be an instance of a nested class created to capture that state.
If this is all in memory, just keeping the delegate itself as the hash key will be okay - although it may mean that some objects which clients would expect to be garbage collected hang around. If you need to serialize this to a database, it gets hairier.
Could you make your method accept a cache key (e.g. a string) as well? (That's assuming an in memory cache is inadequate.)
Keeping the cached results in a Dictionary<Predicate<Foo>,List<Foo>> is awkward for me because I want the ASP.NET cache to handle expiry for me rather than caching all results forever, but it's otherwise a good solution. I think I'll end up going with Will's Dictionary<Predicate<Foo>,string> to cache a string that I can use in the ASP.NET cache key.
Some initial tests suggest that delegate equality does the "right thing" as others have said, but Delegate.GetHashCode is pathologically unhelpful. Reflector reveals
public override int GetHashCode()
{
return base.GetType().GetHashCode();
}
So any Predicate<Foo> returns the same result.
My remaining issue was how equality works for anonymous delegates. What does "same method called on the same target" mean then? It seems that as long as the delegate was defined in the same place, references are equal. Delegates with the same body defined in different places are not.
static Predicate<int> Test()
{
Predicate<int> test = delegate(int i) { return false; };
return test;
}
static void Main()
{
Predicate<int> test1 = Test();
Predicate<int> test2 = Test();
Console.WriteLine(test1.Equals( test2 )); // True
test1 = delegate(int i) { return false; };
test2 = delegate(int i) { return false; };
Console.WriteLine(test1.Equals( test2 )); // False
}
This should be OK for my needs. Calls with the predefined predicates will be cached. Multiple calls to one method that calls FindAll with an anonymous method should get cached results. Two methods calling FindAll with apparently the same anonymous method won't share cached results, but this should be fairly rare.
Unless you're sure Delegate's implementation of GetHashCode is deterministic and doesn't result in any collisions I wouldn't trust it.
Here's two ideas. First, store the results of the delegates within a Predicate/List dictionary, using the predicate as the key, and then store the entire dictionary of results under a single key in the cache. Bad thing is that you lose all your cached results if the cache item is lost.
An alternative would be to create an extension method for Predicate, GetKey(), that uses an object/string dictionary to store and retrieve all keys for all Predicates. You index into the dictionary with the delegate and return its key, creating one if you don't find it. This way you're assured that you are getting the correct key per delegate and there aren't any collisions. A naiive one would be type name + Guid.
The same instance of an object will always return the same hashcode (requirement of GetHashCode() in .Net). If your predicates are inside a static list and you are not redefining them each time, I can't see a problem in using them as keys.

Categories