arrays - c# 单参数函数数组,每个函数具有不同类型的参数

标签 arrays c#-4.0 generics casting

这实际上是一个由两部分组成的问题。

<强>1。如何将参数不同类型的函数数组存储在 Array 或 IEnumerable 中

是否可以编写如下代码:

Func<object, bool> fObj = (o) => false;
Func<Animal, bool> fAni = (a) => false;
Func<Cat, bool> fCat = (c) => true;
var funcArray = new Function1Array<bool>(fObj, fAni, fCat);

哪里Function1Array<T>需要类似 (params Func<?, T>[] funcs) ,即使 c# 不允许通用通配符

<强>2。假设问题 1 可以完成,是否可以检查一个对象是否与其中一个函数的参数类型相同,如果是,则强制转换为该对象

示例:

Cat myCat = new Cat();
funcArray.invokeFirstMatch(myCat); // Invokes fCat(myCat)

object myCat2 = new Cat();          // Declared as object instead of Cat
funcArray.invokeFirstMatch(myCat2); // Invokes fCat(myCat2)

Dog myDog = new Dog();
funcArray.invokeFirstMatch(myDog); // Invokes fObj(myDog)

我的猜测是,如果不以某种方式包装每个函数,这两个问题都是不可能的,因为 Func<Cat, bool>不是 Func<object, bool> 的子类型这意味着没有直接的方法来以这种方式存储函数数组。

最佳答案

你可以这样做:

public class Function1Array<TOut> : IEnumerable
{
    private readonly List<Delegate> funcs = new List<Delegate>();

    public void Add<T>(Func<T, TOut> f)
    {
        this.funcs.Add(f);
    }

    public TOut InvokeFirstMatch<T>(T arg)
    {
        Delegate first = this.funcs.FirstOrDefault(d => d.GetType().GetGenericArguments()[0] == typeof(T));
        if (first == null) throw new ArgumentException("No match");
        return ((Func<T, TOut>)first)(arg);
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        return this.funcs.GetEnumerator();
    }
}

您可以使用集合初始化程序对其进行初始化:

var arr = new Function1Array<bool> { fObj, fAni, fCat };

请注意,这需要参数类型完全匹配,尽管您可以更改为 FirstOrDefault 指定的谓词以使用 IsAssignableFrom

InvokeFirstMatch 的泛型参数意味着搜索是根据参数的静态类型完成的。您可以改用运行时类型:

public TOut InvokeFirstMatch(object arg)
{
    var argType = arg.GetType();
    Delegate first = this.funcs.FirstOrDefault(d => d.GetType().GetGenericArguments()[0] == argType);
    if (first == null) throw new ArgumentException("No match");
    return (TOut)first.DynamicInvoke(Convert.ChangeType(arg, argType));
}

关于arrays - c# 单参数函数数组,每个函数具有不同类型的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16597185/

相关文章:

c - 通过指针数组进行算术 for 循环

javascript - 解析 JSON 以获取 JavaScript 中对象内数组中的值

c# - 为什么我会收到 XML 文档中有错误的错误消息?

.net - 未知软件异常 0xe0434352

java - 如何解决 Java 通用通配符限制

c++ - 如何有效地从数组中提取唯一值?

c - 将数组传递给函数的语法

wpf - 比较剪贴板中的 IDataObject

java - 访问 "nested"通用类型

Java 和 Spring Bean : Create a bean with multiple Generic Types