I have a bunch of methods which I want to check some metadata of, all of them have different parameters but the parameters all derive from BaseClass
.
public void CheckMethod(Func<BaseClass, Object> func)
{
// Check method metadata here
}
public Object MethodToCheck(DerivedClass foo)
{
// Whatever...
}
public void Test()
{
CheckMethod(MethodToCheck);
}
Code fails on CheckMetadata(MethodToCheck)
, becuase MethodToCheck has a DerivedClass as parameter and not a BaseClass. I've tried using generics:
public void CheckMethod<T>(Func<T, Object> func)
...
CheckMethod<DerivedClass>(MethodToCheck);
I would like the call to CheckMethod to be as little to type as possible and would prefer to only call it with CheckMethod(MethodToCheck)
. Is this possible?
A Func in C# is a way to define a method in-line that has a return value. There is a similar concept of an Action that doesn't have a return value, but we'll get to that in a sec. The return value's type is always the last generic parameter on the Func 's definition.
Func<T, TResult> defines a function that accepts one parameter (of type T) and returns an object (of type TResult). In your case, if you want a function that takes a Person object and returns a string...you'd want Func<Person, string> which is the equivalent of: string Function(Person p) { return p.Name; }
C# Func simple example string GetMessage() { return "Hello there!"; } Func<string> sayHello = GetMessage; Console. WriteLine(sayHello()); In the example, we use the Func delegate which has no parameters and returns a single value. This is the function to which we refer with the help of the Func delegate.
Func<TResult> represents a method taking 0 arguments and returning an object of TResult , whereas Action<T> represents a method returning void. You need two different delegates as you can't specify void as a type argument.
Check out the MSDN page on covariance and contravariance. The article seems to suggest that you cannot achieve this in prior versions.
In case you are stuck with an older version, I would suggest that you explore the visitor pattern.
How about something like
public void CheckMethod<T>(Func<T, Object> func) where T : BaseClass
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With