【问题标题】:C# delegate for two methods with different parameters具有不同参数的两个方法的 C# 委托
【发布时间】:2008-12-18 08:36:01
【问题描述】:

我正在使用以下方法:

public void M1(Int32 a)
{
  // acquire MyMutex
  DoSomething(a);
  // release MyMutex
}

public void M2(String s, String t)
{
  // acquire MyMutex
  DoSomethingElse(s, t);
  // release MyMutex
}

从我目前发现的情况来看,似乎不可能将单个委托用于具有不同签名的两个方法。

有没有其他替代方法来写这样的东西:

public void UsingMutex(...)
{
  // acquire MyMutex
  ...
  // release MyMutex
}

UsingMutex(M1);
UsingMutex(M2);

目前我所能想到的就是使用两个委托和一个布尔标志来知道要调用哪个委托,但这不是一个长期的解决方案。

可以将泛型与委托结合起来吗?如果是这样,您是否有任何类型的文档的链接?

环境:C# 2.0

【问题讨论】:

    标签: c# generics delegates


    【解决方案1】:

    当然,您可以将委托与泛型混合使用。在 2.0 中,Predicate<T> 等就是很好的例子,但是你必须有相同数量的参数。在这种情况下,也许一种选择是使用捕获将 args 包含在委托中?

        public delegate void Action();
        static void Main()
        {
            DoStuff(delegate {Foo(5);});
            DoStuff(delegate {Bar("abc","def");});
        }
        static void DoStuff(Action action)
        {
            action();
        }
        static void Foo(int i)
        {
            Console.WriteLine(i);
        }
        static void Bar(string s, string t)
        {
            Console.WriteLine(s+t);
        }
    

    请注意,Action 是在 .NET 3.5 中为您定义的,但您可以为 2.0 目的重新声明它;-p

    注意匿名方法(delegate {...})也可以参数化:

        static void Main()
        {
            DoStuff(delegate (string s) {Foo(5);});
            DoStuff(delegate (string s) {Bar(s,"def");});
        }
        static void DoStuff(Action<string> action)
        {
            action("abc");
        }
        static void Foo(int i)
        {
            Console.WriteLine(i);
        }
        static void Bar(string s, string t)
        {
            Console.WriteLine(s+t);
        }
    

    最后,C# 3.0 使用“lambdas”让这一切变得更容易和更漂亮,但这是另一个话题;-p

    【讨论】:

    • “一秒钟内的例子......” - 确保你得到那些“最快的枪”点? =)
    • @Erik:先做一个“粗略”的帖子,然后提供更多细节,避免其他人通过写一个大致相似的答案来浪费时间。看到其他人发布了类似的内容,我已经多次停止写答案。这一点越早,IMO 就越好。
    • 同意。我花了时间添加详细的答案,只是发现其他人说了同样的话并在我之前发布了它。然后我最终删除了我的答案,浪费了我的时间=\
    • 如果您希望 DoStuff 决定将哪些值传递给争论怎么办?
    • @WDUK 然后将其设为Action&lt;int, string&gt; 或其他任何名称并调用action(123, "abc");
    【解决方案2】:

    是的,可以将泛型与委托结合起来。

    public delegate void Action<T>(T x);
    public delegate void Action<T,U>(T x, U y);
    
    public void UsingMutex<T>(Action<T> x, T t) {
        // acquire mutex...
        x(t);
        // release mutex...
    }
    public void UsingMutex<T,U>(Action<T,U> x, T t, U u) {
        // acquire mutex...
        x(t, u);
        // release mutex...
    }
    

    但是您仍然必须使用重载来处理不同数量的参数。

    【讨论】:

      【解决方案3】:

      如果您查看框架中的Func&lt;T&gt;Action&lt;T&gt; 委托,您会发现它们定义了许多具有不同数量参数的类似委托。您可以使用泛型,但这并不能解决您正在谈论的参数数量问题。

      【讨论】:

      • 不过,它们在 .NET 2.0 中不可用。
      • @Mehrdad - 不过,声明它们很简单。或者只包含也声明它们的 LINQBridge
      • 根据 MSDN 文档,Action 实际上在 2.0 中得到支持。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-08
      • 1970-01-01
      • 2015-07-27
      • 1970-01-01
      相关资源
      最近更新 更多