JOSEFtw
JOSEFtw

Reputation: 10071

Cast func parameter type to object type

I have the following func:

var instance = new MyInstance();
var method = instance.GetType().GetMethod("MyMethod");
Func<bool, PropertyInfo, string, MyClass, object> myFunc = CreateFunc(instance, method);

private static Func<bool, PropertyInfo, string, MyClass, object> CreateFunc(
    object instance,
    MethodInfo method)
{
    var propertyHandlerInterface = instance.GetType().GetInterface(typeof(IPropertyHandler<>).Name);
    var valueType = propertyHandlerInterface.GetGenericArguments().First();
    var funcType = typeof(Func<,,,,>);
    var type = funcType.MakeGenericType(
        valueType,
        typeof(PropertyInfo),
        typeof(string),
        typeof(MyClass),
        typeof(object));
    return (Func<bool, PropertyInfo, string, MyClass, object>)Delegate.CreateDelegate(
        type,
        instance,
        method);
}

I can call it like this:

var myValue = true;
var result = myFunc(myValue, somePropertyInfo, "some string", someMyClassInstance);

I need to be able to cast the first parameter bool to object so that the func looks like this...

Func<object, PropertyInfo, string, MyClass, object> myFunc = CreateMyFunc();

...so I can call it like this:

object myValue = true; // <-- This is key, myValue is of type object.
var result = myFunc(myValue, somePropertyInfo, "some string", someMyClassInstance);

How would I achieve this?

To clarify: I want my CreateFunc to have the following signature:

private static Func<object, PropertyInfo, string, MyClass, object> CreateFunc(
    object instance,
    MethodInfo method)

instead of

private static Func<bool, PropertyInfo, string, MyClass, object> CreateFunc(
    object instance,
    MethodInfo method)

But I don't know how to cast my delegate to that type.

Upvotes: 1

Views: 808

Answers (2)

MartinM43
MartinM43

Reputation: 101

I have a suggestion (how to change the type of an "object"). I hope this is the "hint" you are looking for.

System.Convert.ChangeType(sourceObject, typeof(TargetType));

Upvotes: 0

Peter Duniho
Peter Duniho

Reputation: 70652

Given, for example, a Func<bool, object> instance where you instead want a Func<object, object> instance, the simplest thing is to just wrap it in a lambda and cast the argument passed to it:

Func<bool, object> func1 = ...;
Func<object, object> func2 = o => func1((bool)o);

Keeping in mind, of course, that by doing so you have removed the type-safety the C# compiler would normally provide when using the delegate. A caller could invoke func2 passing a parameter that is not a bool value, and an InvalidCastException would be thrown in that case.

If you can't guarantee that the caller using the delegate you've created in this way will always pass a bool value as the object parameter, then you'll need to include some fall-back mechanism in the wrapped delegate, e.g. check the type of the o parameter value and if it's not a bool, then pass a default value to the func1 delegate, or simply return some default return value instead of calling the func1 delegate.

For example:

Func<object, object> func2 = o => o is bool f ? func1(f) : null;

Upvotes: 2

Related Questions