【问题标题】:"dynamic" for anonymous delegates?匿名代表的“动态”?
【发布时间】:2012-05-31 02:43:42
【问题描述】:

我想知道是否有可能使变量的“动态”类型适用于匿名委托。

我尝试了以下方法:

dynamic v = delegate() {
};

然后我收到以下错误消息:

Cannot convert anonymous method to type 'dynamic' because it is not a delegate type

不幸的是,以下代码也不起作用:

Delegate v = delegate() {
};
object v2 = delegate() {
};

如果我想创建一个接受任何类型的委托的方法,即使是内联声明的,我该怎么办?

例如:

class X{
    public void Y(dynamic d){
    }
    static void Main(){
        Y(delegate(){});
        Y(delegate(string x){});
    }
}

【问题讨论】:

  • 有什么理由不使用Func<>Action<>
  • @Jamiec 我想是因为这不符合不关心代表签名的标准。也就是说,它可以归结为使用 object[] 参数调用 Invoke,然后可以用 Func<> 表示。
  • 你没有在那里声明任何委托类型。
  • @AdamHouldsworth - 是的,重新阅读了这个问题,我现在明白了,但这没有多大意义。您必须对委托某事,这意味着您的程序必须了解委托的 I/O。
  • @Jamiec 因为 Func 和 Action 具有 FIX 计数/参数类型。每次都必须指定。我不想这样做。

标签: c# dynamic delegates anonymous-delegates


【解决方案1】:

这可行,但看起来有点奇怪。你可以给它任何委托,它会运行它并返回一个值。

您还需要指定匿名方法签名在某些时候,以便编译器能够理解它,因此需要指定Action<T>Func<T> 或其他任何内容。

Why can't an anonymous method be assigned to var?

    static void Main(string[] args)
    {
        Action d = () => Console.WriteLine("Hi");
        Execute(d); // Prints "Hi"

        Action<string> d2 = (s) => Console.WriteLine(s);
        Execute(d2, "Lo"); // Prints "Lo"

        Func<string, string> d3 = (s) =>
        {
            Console.WriteLine(s);
            return "Done";
        };
        var result = (string)Execute(d3, "Spaghettio"); // Prints "Spaghettio"

        Console.WriteLine(result); // Prints "Done"

        Console.Read();
    }

    static object Execute(Delegate d, params object[] args)
    {
        return d.DynamicInvoke(args);
    }

【讨论】:

  • 你能不能把Execute 的第二个参数变成params 让它看起来不那么奇怪?见:rextester.com/KMX49960
  • 这是我已经得到的。这里的问题是,我必须为我传递执行的每个委托指定 Action 的签名。带着这个问题,我想找到一种方法来避免这种情况。
  • @VanCoding 我想不出办法来避免这种情况,但话虽如此,这并不重要或会产生任何问题。您知道签名是什么,因为您正在内联创建签名,您只需将其转换为该签名,然后再将其提供给方法。
  • @AdamHouldsworth 太可悲了,因为对我来说指定它似乎完全没有必要......这使得整个代码非常尴尬......没有开发人员想要两次定义类型......这不是问题知道类型,这是代码设计的问题。
  • @VanCoding 这可能与您不能将 lambda 分配给 var 的原因相同。
【解决方案2】:

如果您为每个委托声明一个类型,它就会起作用。

// Declare it somewhere
delegate void DelegateType(string s);

// The cast is required to make the code compile
Test((DelegateType)((string s) => { MessageBox.Show(s); }));

public static void Test(dynamic dynDelegate)
{
    dynDelegate("hello");
}

【讨论】:

  • 所以我必须先转换每个匿名代表,然后再将其传递给测试?
  • 是的,否则无法编译。
【解决方案3】:
Action _;
dynamic test = (_ = () => Console.WriteLine("Test"));
test() // Test

【讨论】:

  • 请在您的代码中添加解释,以便于理解。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-15
  • 1970-01-01
  • 2013-07-12
  • 2018-05-19
相关资源
最近更新 更多