You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将特定签名的任意委托转换为Func<MyClass, object[], bool>?

Is it possible to convert delegates matching specific signatures to Func<MyClass, object[], bool>?

Absolutely, this is totally feasible! The core idea is to wrap your existing delegates in a lambda (or build a dynamic wrapper via expression trees) that takes the MyClass instance and an object[] of arguments, then unpacks and converts those arguments to match the original delegate's parameter types before invoking it.

Manual Adapter Example

For each of your specific methods, you can create a direct Func<MyClass, object[], bool> wrapper explicitly:

First, let's define our example types and methods:

public class MyClass { }
public class AnotherClass { }

public static bool FirstMethod(MyClass foo, int integer, string text)
{
    return integer > 0 && !string.IsNullOrEmpty(text);
}

public static bool SecondMethod(MyClass foo, string text, AnotherClass bar)
{
    return text != null && bar != null;
}

Now wrap them into the desired Func type:

// Wrap FirstMethod
Func<MyClass, object[], bool> firstFunc = (myObj, args) => 
    FirstMethod(myObj, (int)args[0], (string)args[1]);

// Wrap SecondMethod
Func<MyClass, object[], bool> secondFunc = (myObj, args) => 
    SecondMethod(myObj, (string)args[0], (AnotherClass)args[1]);

You can then call these wrappers like so:

var myInstance = new MyClass();
bool firstResult = firstFunc(myInstance, new object[] { 42, "Stack Overflow" });
bool secondResult = secondFunc(myInstance, new object[] { "Hello", new AnotherClass() });

Generic Reusable Solution

If you have many such delegates and don't want to write manual wrappers for each, you can use expression trees to build a generic converter. This automatically handles the argument unpacking and type conversion:

public static Func<MyClass, object[], bool> ConvertToTargetDelegate<TDelegate>(TDelegate del) 
    where TDelegate : Delegate
{
    var method = del.Method;

    // Validate the delegate meets our requirements
    if (method.ReturnType != typeof(bool))
        throw new ArgumentException("Delegate must return a boolean value.");
    
    var parameters = method.GetParameters();
    if (parameters.Length == 0 || parameters[0].ParameterType != typeof(MyClass))
        throw new ArgumentException("Delegate's first parameter must be of type MyClass.");

    // Build expression tree nodes for the Func parameters
    var myClassParam = Expression.Parameter(typeof(MyClass), "myObj");
    var argsParam = Expression.Parameter(typeof(object[]), "args");

    // Build the list of arguments for the original method call
    var callArguments = new List<Expression> { myClassParam };
    for (int i = 1; i < parameters.Length; i++)
    {
        var targetType = parameters[i].ParameterType;
        // Get the argument from the object array and convert it to the target type
        var argIndex = Expression.Constant(i - 1);
        var argExpr = Expression.ArrayIndex(argsParam, argIndex);
        var convertedArg = Expression.Convert(argExpr, targetType);
        callArguments.Add(convertedArg);
    }

    // Create the method call expression
    var methodCall = Expression.Call(Expression.Constant(del.Target), method, callArguments);
    // Compile the expression into a Func
    var lambda = Expression.Lambda<Func<MyClass, object[], bool>>(methodCall, myClassParam, argsParam);
    
    return lambda.Compile();
}

Using this generic converter is straightforward:

// Convert FirstMethod
var firstGenericFunc = ConvertToTargetDelegate((Func<MyClass, int, string, bool>)FirstMethod);

// Convert SecondMethod
var secondGenericFunc = ConvertToTargetDelegate((Func<MyClass, string, AnotherClass, bool>)SecondMethod);

// Call them just like the manual wrappers
bool genericFirstResult = firstGenericFunc(myInstance, new object[] { 10, "Test" });
bool genericSecondResult = secondGenericFunc(myInstance, new object[] { "Example", new AnotherClass() });

Key Notes

  • When calling the wrapped Func, ensure the object[] contains exactly the right number of arguments in the correct order, and that each argument can be converted to the original parameter type (e.g., don't pass a string where an int is expected—this will throw a cast exception).
  • For instance methods, make sure the target object (the instance the delegate is bound to) remains valid for the lifetime of the wrapped Func.
  • The expression tree approach incurs a one-time compilation cost, but is much more scalable if you have many delegates to convert.

内容的提问来源于stack exchange,提问作者Chilli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:53:46