【问题标题】:Can I call an Action<T> stored as delegate我可以调用存储为委托的 Action<T>
【发布时间】:2013-11-07 10:21:44
【问题描述】:

我将操作存储为委托。我也将 T 存储为接口。

以后有什么方法可以调用 Action 并传递对象吗?

public class MyAction {
    public IMyObject IMyObject { get; set; }
    public Delegate myDelegate { get; set; }
    public Type IMyObjectType { get; set; }
}

IMyObject 是一个空接口

public interface IMyObject { }

我从 Action 回调创建 MyAction 实例

public static MyAction Factory<T>(Action<T> callback) {
            return new MyAction() {
                myDelegate = callback, IMyObjectType = typeof (T)
            };
        }

是否可以调用委托并传递 IMyObject?

稍后我在尝试调用 Delegate(Action) 之前设置了 IMyObject

【问题讨论】:

    标签: c# c#-4.0 generics casting delegates


    【解决方案1】:

    如果类型不固定(如:它只是Delegate,而你不知道T),那么你可以使用:

    action.myDelegate.DynamicInvoke(args);
    

    但这相对较慢。如果你做了很多,你会想避免这种情况。坦率地说,在整个过程中只使用Action&lt;object&gt;(或类似的)并在回调中强制转换会更有效 - 然后您的代码将知道委托类型并可以使用常规调用。

    【讨论】:

      【解决方案2】:

      让 MyAction 也通用

      class MyAction<T> where T : IMyObject
      {
         public T IMyObject { get; set; }
         public Action<T> action { get; set; }
         public Type IMyObjectType { get { return typeof(T); }
      }
      

      问题是你不能在编译时不知道参数类型的情况下创建 MyAction,除非你使用反射创建它(如果你多次调用动作并想要优化执行,这可能很有用)。

      使用DynamicInvoke调用操作 (它使用反射并且非常慢)。

      您也可以考虑将其设为包含参数的Action。这取决于您的要求。

      myDelegate = () => callback(argument);
      

      【讨论】:

      • 请定义很慢。这是什么时候出现的问题?它会滞后于您的 UI,还是只会在数千次迭代中成为问题?
      • @Gusdor 的表现是相对的;要知道这是否是对您而言的问题,您应该查看在您的场景中的性能。缓慢的警告是非常有效的。
      • 感谢@MarcGravell,这是我希望从 Stefan 那里得到的解释。 “X 很慢,避免避免”是一个真正让我感到厌烦的答案,尤其是在没有其他方法可以满足 OP 要求的情况下。
      • 我记得其中一位 C# 大师的帖子说它比正常调用慢了大约 170 倍。
      【解决方案3】:

      您必须使用Delegate.DynamicInvoke 来调用无类型的Delegate

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-09
        • 2011-01-17
        • 1970-01-01
        • 2017-07-02
        • 1970-01-01
        • 2018-09-22
        • 1970-01-01
        相关资源
        最近更新 更多