No, it's not possible. Constraints are defined when they are declared. In this case, the method is not generic, the class is (it's a non-generic method of a generic class). So the constraints can be only declared on the class itself.
views:
728answers:
5It depends on what you want.
Since the class is compiled once, and the magic with generics also relies on the runtime, there's no way to make a class that has some methods in some cases, and other methods in other cases. Either the methods are there, or they aren't.
So basically, there's no way to declare MyBaseClass so that the following happens:
MyBaseClass<Int32> bc;
bc. <-- intellisense does not show ShowThisMethod here
MyBaseClass<SomeTypeImplementingIMyInterface> bc2;
bc2. <-- intellisense DOES show ShowThisMethod here
... that is... by itself.
You can "trick" the compiler and intellisense into giving you what you're asking for, but know that this gives you other limitations and challenges that might need to be solved.
Basically, by adding an extension method to a static class declared alongside MyBaseClass, you can make intellisense, and the compiler, behave as if the method is only present for MyBaseClass when T has some specific rules, as you're asking for.
However, since the method in question will be a static method, defined outside of MyBaseClass, there's limits to how much of the internals of MyBaseClass you can access, and you can't access the method inside MyBaseClass, so it depends on what you want to accomplish and whether you can live with the limitations or not.
Anyway, here's the extension method. Note that you remove it completely from MyBaseClass at the same time:
public static class MyBaseClassExtensions
{
public static IQueryable<T> ShowThisMethod<T>(this MyBaseClass<T> mbc)
where T: class, IMyInterface
{
...
}
}
Will this do what you want? The method will be visible to anyone, but not necessarily useable...
public class MyBaseClass<T> where T: class
{
public IQueryable<R> ShowThisMethod() where R: T, IMyInterface
{
Debug.Assert(typeof(R) == typeof(T));
// stuff.
}
}
Also note that ShowThisMethod is redefining T in the context of ShowThisMethod. It is not the same T as defined by the class.
Specifying a different Type parameter where the new one inherits from the one defined by the class would be the best approach, though that ends up requring the caller to have to specify the generic Type twice.
You could define another class that inherits MyBaseClass and redefine the constraint :
public MyOtherClass<T> : MyBaseClass<T> where T : class, IMyInterface
{
public IQueryable<T> ShowThisMethod()
{
// stuff.
}
}