I've been a little puzzled with Delegates and Generic Methods.
Is it possible to assign a delegate to a method with a generic type parameter?
I.E:
//This doesn't allow me to pass a generic parameter with the delegate.
public delegate void GenericDelegate<T>()
someDelegate = GenericMethod;
public void GenericMethod<T>() where T : ISomeClass
{
}
I'm trying to pass this delegate into the function with a generic type of the interface that the method is expecting, with a function like this:
void CheckDelegate(GenericDelegate<ISomeClass> mechanism);
so that I can use the delegate like so:
someDelegate<ImplementsSomeClass>();
I tried the following:
And I have no compilation errors. Is it a runtime problem or did I misunderstand your problem description?
It is possible to have a single "thing" which can operate upon multiple parameter types, but the
Delegate
class is not suitable for that. Instead, you'll need to define an interface. As a simple example:Even if the system had a pre-defined delegate type with a by-ref parameter (so that e.g.
ActByRef<ICloneable>
would have signaturevoid Invoke(ref ICloneable p1)
) such a delegate only be used on a variable of exact typeICloneable
. By contrast, a single object of non-generic class typeCloner
is able to provide a method suitable for use with any storage location type which implementsICloneable
. Note also that if the method is passed aref
to a variable holding a reference to a boxed value-type instance, it will replace it with a reference to a copy of the instance, but if it is passed aref
to a value-type variable, it leave it as is (unless the value-type holds its state in a mutable class object to which it holds a reference--a very dodgy pattern--sayingStructType foo = (StructType)(bar.Clone());
would be equivalent to justfoo = bar
; the structure type may want to implementICloneable
so to allow it to take part in a deep-cloning hierarchy, but that doesn't mean itsClone
method needs to do anything.Your question makes no sense because you can't ever use an open generic type to declare a storage location (like a local variable or field). It must always be closed.
I understand you want to pass a
GenericDelegate<T>
to a method taking such a value as an argument. But even then the delegate type becomes closed withT
as the generic type parameter.In your sample code you write
but what type is
someDelegate
supposed to have? It must either be obviously closed (GenericDelegate<string>
) or closed with a generic type parameter from the outer scope:I hope I understood your problem. If not, please clarify. If you elaborate a little on what you want to accomplish I'll try to suggest a practical solution.
Other languages like Haskell do have support for passing around values of open generic types (in other words, you can have a variable of type
IEnumerable<>
). This is required to implement monads. The CLR does not have that feature.New thought: instead of a delegate you could create a non-generic base type with a generic method that can be overridden:
Hope that covers your scenario. You can not freely pass any
CheckHandler
around. ItsCheck
method can then be called with an arbitrary type argument.Updated the example to support method as parameter which is just demonstating how to call generic delegate as parameter of other method.