【问题标题】:Create generic instance with delegate arg使用委托 arg 创建通用实例
【发布时间】:2011-03-09 09:41:01
【问题描述】:

我试图通过引入泛型来重构一些代码,但我被卡住了。我正在尝试创建 T 的新实例,但问题是,T 在构造函数中有一个委托参数。我的目标是这样的:

public delegate IOrders DoStuffDelegate(); 


public class GenericBoss<T> where T:Worker
{

    public void DelegateWork()
    {
        T worker = Activator.CreateInstance(typeof(T), new[]{GiveOrders})
        worker.Work();
    }

    public IOrders GiveOrders()
    {
        return new OrderFromTheBoss();
    }
}

public class Worker
{
    private readonly DoStuffDelegate _takeOrders;

    public Worker(DoStuffDelegate takeOrders)
    {
        _takeOrders = takeOrders;
    }

    public void Work()
    {
        _takeOrders(); 
    }
}

但是,这不起作用,因为在 [Activator] 中只允许 [object] 类型作为参数。我不允许更改构造函数,因此无法将委托移动到其他地方。

有没有出路,或者泛型不是这里的选择?

问候, 莫腾

【问题讨论】:

    标签: c# .net generics delegates


    【解决方案1】:

    问题在于编译器不知道您要将方法组转换为哪个委托。如果它总是DoStuffDelegate,你可以这样做:

    object[] args = new object[] { new DoStuffDelegate(GiveOrders) };
    T worker = (T) Activator.CreateInstance(typeof(T), args);
    

    DoStuffDelegate giveOrders = GiveOrders;
    object[] args = new object[] { giveOrders };
    T worker = (T) Activator.CreateInstance(typeof(T), args);
    

    如果每个T 的委托类型都不同,那就更难了——您可能需要调用Delegate.CreateDelegate 来创建通过反射发现的适当委托类型的实例:(

    【讨论】:

    • 我认为Activator.CreateInstance 在这种情况下会返回一个对象?应应用 as 演员或通用版本。
    • @Danny:是的,演员阵容是必需的 - 将添加。我专注于事物的争论方面,我认为这是 OP 的原始问题 :)
    • 是的,我不得不将它转换回 T,但它起作用了。谢谢你。你让我的代码更漂亮了 :o)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多