如何将委托传递给一个方法,其中委托是非静态的?

时间:2010-12-05 05:11:01

标签: c# delegates instance idisposable using

我刚开始理解委托,我有一个实现IDisposable的类:

public class MyClass : IDisposable
{
  public delegate int DoSomething();

  public int Zero() {return 0;}
  public int One() {return 1;}

  public void Dispose()
  {
    // Cleanup
  }
}

使用MyClass的方法(在另一个类中定义):

public class AnotherCLass
{
    public static void UseMyClass(MyClass.DoSomething func)
    {
      using (var mc = new MyClass())
      {
        // Call the delegate function
        mc.func(); // <-------- this is what i should actually call
      }
    }
}

实际的问题如何将Zero()函数传递给UseMyClass方法?我是否必须创建MyClass的实例(我想避免这种情况......)?

public static void main(string[] args)
{
  // Call AnotherClass method, by passing Zero()
  // or One() but without instatiate MyCLass
  AnotherClass.UseMyClass(??????????);
}

3 个答案:

答案 0 :(得分:2)

您的意图是该实例是由委托的调用者提供的,而不是代理的创建者吗? C#确实支持这样一个未绑定的委托,它被称为 open delegate ,并且该实例成为参数。

您必须使用Delegate.CreateDelegate来创建一个开放的委托,如下所示:

public class MyClass : IDisposable
{
  public delegate int DoSomething();

  public int Zero() {return 0;}
  public int One() {return 1;}

  public void Dispose()
  {
    // Cleanup
  }
}

public class AnotherCLass
{
    public static void UseMyClass(Converter<MyClass,int> func)
    {
      using (var mc = new MyClass())
      {
        // Call the delegate function
        func(mc);
      }
    }
}

AnotherClass.UseMyClass(
    (Converter<MyClass, int>)Delegate.CreateDelegate(
        typeof(Converter<MyClass, int>),
        typeof(MyClass).GetMethod("One")
    )
);

当然,你可以用垫片更轻松地做到这一点:

AnotherClass.UseMyClass( mc => mc.One() ); // C# 3 or later
AnotherClass.UseMyClass( delegate(MyClass mc) { return mc.One(); } ); // C# 2

答案 1 :(得分:1)

因为它是一个实例方法,如果你想调用它,你需要一个实例。这就是CLR的工作原理。但是,您可以选择两种方式:

  • 使成员函数保持静态。如果它们像返回静态值一样简单,那么它们就没有理由成为实例方法。但是,如果您确实需要实例数据......
  • 使用单例实例。这样,每次要调用静态方法时都不需要创建新实例。

你可以这样做:

public class MyClass
{
    private static MyClass singletonInstance;
    public static MyClass SingletonInstance
    {
        get
        {
            if (singletonInstance == null)
            {
                singletonInstance = new MyClass();
            }
            return singletonInstance;
        }
    }

    // the rest of your class implementation
}

然后,您可以像这样调用静态方法:

AnotherClass.UseMyClass(MyClass.SingletonInstance.Zero);

答案 2 :(得分:0)

可以在没有实例化的情况下完成。这是你如何做到的:


public static void main(string[] args)
{
  // Call AnotherClass method, by passing Zero()
  // or One() but without instatiate MyCLass
  AnotherClass.UseMyClass((new MyClass()).Zero);
}