存储和调用通用类型的委托 [英] Storing and calling generically-typed delegates

查看:47
本文介绍了存储和调用通用类型的委托的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果不依靠反思,我正在寻找的东西可能将无法实现.如果是这样,我仍然想知道实现此目标的最佳方法.

What I'm looking for is probably not going to be possible without resorting to reflection. If that's the case, I'd still want to know the best way to pull it off.

从本质上讲,这就是我希望代码看起来像的样子:

Essentially, this is what I want my code to look like:

var instance = new MyClass();
instance.Add<int, string>(x => x.ToString());
instance.Add<string, Warehouse>(x => Warehouse.LookupByName(x));
instance.Add<Warehouse, IList<Supplier>>(x => x.Suppliers());

instance.Chain(3);    // should call each lambda expression in turn

我的问题是,如何将这些具有不同签名的代表存储在MyClass的列表中?以及以后如何在需要时使用每个参数的返回值作为下一个参数的输入参数来调用它们?

My question is, how can I store these delegates, each with a different signature, in a list in MyClass? And how can I call them later on when I want to, using the return value from each one as the input parameter to the next one?

MyClass的内部很可能是List的一团糟.但是我什至不知道从哪里开始.

The inside of MyClass may very well be a mess of List's and all that. But I'm not even sure where to start on this.

(最初,我想调用 new MyClass< int,string,Warehouse,IList< Supplier>>().但是,由于没有类型参数数组",我放弃了这种方法.)

(Originally, I wanted to call new MyClass<int, string, Warehouse, IList<Supplier>>(). However, since there's no "type parameter array", I gave up on that approach.)

推荐答案

好吧,您可以将它们全部存储为 Delegate -但棘手的事情是稍后调用它们.

Well, you could store them all as Delegate - but the tricky thing is invoking them later.

如果您能够随时验证下一个委托人的类型正确,例如通过为当前输出"保留 Type 引用,您可以始终存储 List< Func< object,object>> 并进行 Add 方法类似:

If you're able to validate that the next delegate at any time is of the right type, e.g. by holding a Type reference for "the current output" you could always store a List<Func<object, object>> and make your Add method something like:

public void Add<TIn, TOut>(Func<TIn, TOut> func)
{
    // TODO: Consider using IsAssignableFrom etc
    if (currentOutputType != typeof(TIn))
    {
        throw new InvalidOperationException(...);
    }
    list.Add(o => (object) func((TIn) o));
    currentOutputType = typeof(TOut);
}

然后将其全部调用:

object current = ...; // Wherever
foreach (var func in list)
{
    current = func(current);
}

这篇关于存储和调用通用类型的委托的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆