4

We can restrict the type be the class or struct. Can we strict the type be a delegate?

user496949
  • 83,087
  • 147
  • 309
  • 426

2 Answers2

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
  • Is there any workaround? – user496949 Nov 12 '10 at 03:18
  • @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