views:

264

answers:

3

I wanted to derive a class from Predicate<IMyInterface>, but it appears as if Predicate<> is sealed. In my case I wanted to simply return the inverted (!) result of the designated function. I have other ways to accomplish the goal. My question is what might the MS designers have been thinking when deciding to seal Predicate<>?

Without much thought I came up with: (a) simplified their testing, just a time vs cost trade off (b) "no good" could come from deriving from Predicate<>

What do you think?

Update: There are n predicates that are dynamically added to a list of Predicates during an initialization phase. Each is mutually exclusive (if Abc is added, NotAbc wont be added). I observed a pattern that looks like:

bool Happy(IMyInterface I) {...}
bool NotHappy(IMyInterface I) { return !Happy(I); }
bool Hungry(IMyInterface I) {...}
bool NotHungry(IMyInterface I) { return !Hungry(I); }
bool Busy(IMyInterface I) {...}
bool NotBusy(IMyInterface I) { return !Busy(I); }
bool Smart(IMyInterface I) {...}
bool NotSmart(IMyInterface I) {...} //Not simply !Smart

Its not that I can't solve the problem, its that I wonder why I couldn't solve it a certain way.

+3  A: 

Predicate is a delegate. You can not inherit from a delegate type. If you want to get the inverted value, use the following:

Predicate<T> p;
Predicate<T> inverted = t => !p(t);
Omer van Kloeten
+13  A: 

Predicate<T> is a delegate type. You can never derive from delegates.

To be honest, it doesn't sound like inheritance is really appropriate here anyway - just write a method which returns an inverse of the original. It's as simple as this:

public static Predicate<T> Invert<T>(Predicate<T> original)
{
    return t => !original(t);
}
Jon Skeet
+1  A: 

The functionality of a delegate is to handle a list of type safe method pointers. C# designers have decided that there is nothing to add to this functionality and there is no reason to change the behavior to delegates.

So, Jon is right, inheritance is not appropriate here.

Delegates can point to a list of methods. We add to this list with += operator or with Delegate.Combine. If the signature of the method is not void then the result of the last invoked method is returned (if a recall correctly).

Petar Repac