views:

102

answers:

4

I've got an IList<Delegate> that contains some Func<bool>s and some Predicate<T>s, where T varies. I later need to sort out which of these items are Predicate<T>s, but don't want to close the door to adding other Delegate types to the list later, so I do not want to do this by identifying objects by !(current_delegate is Func<bool>).

The highest abstraction below Predicate<T> is MulticastDelegate, which seems unhelpful (would need a non-generic Predicate type under Predicate<T>), and identifying the presence of the generic parameter is also useless given the other generic Delegates that may be present in the list.

The only other thing I've considered is checking the Name of the Type. To me, string comparison is a near-smell, but maybe that is the is the best and/or only way -- you tell me.

What is the best way to definitively determine that an object is any Predicate<T> without knowing the type of T?

A: 

You can have a list of special classes which wrap your delegates and provide additional sorting information. So you'll indirectly solve the problem.

Kerido
Thanks; the list is populated by passing lambda expressions, which would add significant complexity to implementing this.
Jay
+1  A: 
Predicate<int> pred = ...;
var isPreidcate = pred.GetType().GetGenericTypeDefinition() == typeof(Predicate<>);

On another note, if you have a generic list, you shoulnd't need to check the types in it. You may want to rethink your design if you need to check for specific types within a list.

BFree
+6  A: 

Like this:

obj.GetType().GetGenericTypeDefinition() == typeof(Predicate<>)
SLaks
Perfection. One of those things that I'm probably now going to find a good use for at least weekly.
Jay
Yeah, but be prepared to catch the `InvalidOperationException` that will be thrown for nongeneric delegate types--which sounds like they might be a future possibility. To avoid the hassle, check `Type.IsGenericType` before calling this method.
Ben M
A: 

This should work well enough:

public static bool IsPredicate(object obj) {
    var ty = obj.GetType();
    var invoke = ty.GetMethod("Invoke");
    return invoke != null && invoke.ReturnType == typeof(bool);
}

The trick will be when you actually want to call the function, you will need to use reflection.

Here are some tests:

Func<bool> is pred? True
Func<int, bool> is pred? True
Predicate<int> is pred? True
Func<int> is pred? False 
Frank Krueger