Как передать делегат методу, где делегаты не статичны? - PullRequest
2 голосов
/ 05 декабря 2010

Я только начинаю понимать делегатов, у меня есть класс, который реализует 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 ]

2 голосов
/ 05 декабря 2010

Являетесь ли вы намерением, чтобы экземпляр был предоставлен вызывающим лицом делегата, а не его создателем?C # поддерживает такой несвязанный делегат, он называется открытый делегат , и экземпляр становится параметром.

Вы должны использовать 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 голос
/ 05 декабря 2010

Поскольку это метод экземпляра, если вы хотите вызвать его, вам нужен экземпляр.Это просто, как работает 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);
0 голосов
/ 05 декабря 2010

Не может быть сделано без конкретизации.Вот как вы можете это сделать:


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

...