We can restrict the type be the class or struct. Can we strict the type be a delegate?
Asked
Active
Viewed 1,429 times
4
-
You have just tried sub-types of Delegate? Although I would likely use the appropriate signature or Func<...>, etc, if possible. – Nov 12 '10 at 02:27
-
1@user, are you referring to generic constraints? – Kirk Woll Nov 12 '10 at 02:27
-
yes, I am referring to generic constraints – user496949 Nov 12 '10 at 02:37
2 Answers
9
A Delegate
is a class, and you would normally be able to specify a non-sealed class as a constraint. However, the language specification specifically excludes System.Delegate
as a valid constraint in section 10.1.5.
A class-type constraint must satisfy the following rules:
- The type must be a class type.
- The type must not be sealed.
- The type must not be one of the following types: System.Array, System.Delegate, System.Enum, or System.ValueType.
- The type must not be object. Because all types derive from object, such a constraint would have no effect if it were permitted.
- At most one constraint for a given type parameter can be a class type.

Anthony Pegram
- 123,721
- 27
- 225
- 246
-
-
@user - Not a pretty or stable one. It would likely involve reflection, which removes compile-time safety. – Anthony Pegram Nov 12 '10 at 03:21
-
Amazing! Could you show an example of removing compile-time safety? – user496949 Nov 12 '10 at 03:27
-
@user, binarycoder's answer shows something you may try. Where it gets dicey is once you've figured out that the input is a delegate, where do you go from there? How many parameters does the delegate expect? Would you use the return value (if any)? I do not have such a code example. – Anthony Pegram Nov 12 '10 at 04:58
2
As has already been pointed out, the C# specification does not allow a Delegate
generic constraint. Nor are Delegate
subclasses accepted by the compiler as a generic constraint. The best you can do is test and throw an exception. I will show this with a method, but if this is a generic class, the constructor would be a great place to do the check.
public void Foo<T>(T x)
{
if (x == null)
throw new ArgumentNullException("x");
Delegate d = x as Delegate;
if (d == null)
throw new ArgumentException("Argument must be of Delegate type.", "x");
// Use d here.
}

Jason Kresowaty
- 16,105
- 9
- 57
- 84