将 func 参数类型转换为对象类型

时间:2021-05-22 07:28:36

标签: c# reflection delegates

我有以下功能:

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);
}

我可以这样称呼它:

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

我需要能够将第一个参数 bool 转换为 object 以便函数看起来像这样...

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

...所以我可以这样称呼它:

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

我将如何实现这一目标?

澄清:我希望我的 CreateFunc 具有以下签名:

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

代替

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

但我不知道如何将我的委托转换为那种类型。

2 个答案:

答案 0 :(得分:2)

例如,给定一个 Func<bool, object> 实例,您想要一个 Func<object, object> 实例,最简单的方法是将它包装在一个 lambda 中并转换传递给它的参数:

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

当然,请记住,通过这样做,您已经删除了 C# 编译器在使用委托时通常会提供的类型安全。调用者可以调用 func2 传递一个不是值的参数,并且在这种情况下会抛出一个 bool

如果您不能保证使用您以这种方式创建的委托的调用者始终将 InvalidCastException 值作为 bool 参数传递,那么您需要包含一些 fall - 包装委托中的回退机制,例如检查 object 参数值的类型,如果它不是 o,则将默认值传递给 bool 委托,或者简单地返回一些默认返回值而不是调用 {{ 1}} 委托。

例如:

func1

答案 1 :(得分:0)

我有一个建议(如何更改“对象”的类型)。我希望这是您正在寻找的“提示”。

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