【问题标题】:Using an anonymous delegate to return an object使用匿名委托返回对象
【发布时间】:2011-02-06 07:15:45
【问题描述】:

是否可以使用匿名委托来返回对象?

类似这样的:

object b = delegate { return a; };

【问题讨论】:

  • a 来自哪里?此外,您现有的代码只是将 b 分配给委托本身。
  • @BoltClock - 感谢您指出分配问题。
  • 查看有关您的跨线程痛苦的更新

标签: c# delegates language-features


【解决方案1】:

是的,但只能通过调用它:

Func<object> func = delegate { return a; };
// or Func<object> func = () => a;
object b = func();

当然,下面要简单得多...

object b = a;

在cmets中,提到了跨线程异常;这可以修复如下:

如果委托是我们想要在 UI 线程上运行的东西来自一个 BG 线程:

object o = null;
MethodInvoker mi = delegate {
    o = someControl.Value; // runs on UI
};
someControl.Invoke(mi);
// now read o

或者反过来(在 BG 上运行委托):

object value = someControl.Value;
ThreadPool.QueueUserWorkItem(delegate {
    // can talk safely to "value", but not to someControl
});

【讨论】:

  • 如果我试图将aa 所属线程以外的线程上的方法中的某个其他对象进行比较?例如,void Test() { if(a == b){} } 从该方法访问 b 会导致跨线程异常。
  • @Wulfgar a 不“属于”线程;它要么属于一个类实例(如果它是一个字段),要么属于一个方法变量。无论哪种方式,编译器都会从声明委托的范围内“捕获”a 变量;通过创建一个封装对象实例“this”(用于字段)或“变量”本身的类型;引用是因为它随后变成一个字段。
  • @Wulfgar - 要获得跨线程,您必须在做 UI 工作;是的,你可以解决这个问题,但是“如何”取决于哪个代码块是 UI 代码;你能澄清一下吗?
【解决方案2】:

只需在某处声明这些静态函数:

public delegate object AnonymousDelegate();

public static object GetDelegateResult(AnonymousDelegate function)
{
    return function.Invoke();
}

在任何地方都可以像这样使用它:

object item = GetDelegateResult(delegate { return "TEST"; });

甚至像这样

object item = ((AnonymousDelegate)delegate { return "TEST"; }).Invoke();

【讨论】:

    【解决方案3】:
    using System;
    
    public delegate int ReturnedDelegate(string s);
    
    class AnonymousDelegate
    {
        static void Main()
        {
            ReturnedDelegate len = delegate(string s)
            {
                return s.Length;
            };
            Console.WriteLine(len("hello world"));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-01
      相关资源
      最近更新 更多