Запустите метод перед всеми методами класса - PullRequest
22 голосов
/ 08 февраля 2012

Возможно ли это сделать в C # 3 или 4?Может быть, с некоторым отражением?

class Magic
{

    [RunBeforeAll]
    public void BaseMethod()
    {
    }

    //runs BaseMethod before being executed
    public void Method1()
    {
    }

    //runs BaseMethod before being executed
    public void Method2()
    {
    }
}

РЕДАКТИРОВАТЬ

Есть альтернативное решение для этого, сделайте Magic синглтоном и поместите свой код в получатель статического экземпляра.Вот что я сделал:

public class Magic
{

    private static Magic magic = new Magic();
    public static Magic Instance
    {
        get
        {
            magic.BaseMethod();
            return magic;
        }
    }

    public void BaseMethod()
    {
    }

    //runs BaseMethod before being executed
    public void Method1()
    {
    }

    //runs BaseMethod before being executed
    public void Method2()
    {
    }
}

Ответы [ 5 ]

11 голосов
/ 08 февраля 2012

Вы не можете сделать это автоматически в C # - вы, вероятно, должны смотреть на AOP, например с PostSharp .

9 голосов
/ 08 февраля 2012

Для этого есть альтернативное решение, сделайте Magic одноэлементным и поместите свой код в получатель статического экземпляра. Вот что я сделал.

public class Magic{

private static Magic magic;
public static Magic Instance{
  get
    {
   BaseMethod();
    return magic;
    }
}

public void BaseMethod(){
}

//runs BaseMethod before being executed
public void Method1(){
}

//runs BaseMethod before being executed
public void Method2(){
}
}
3 голосов
/ 08 февраля 2012

То, что вы хотите, можно сделать с помощью AOP - некоторые ссылки на .NET C # AOP Framework:

2 голосов
/ 15 июня 2018

Я знаю, что это не ответит на вопрос напрямую.Но это хороший подход - использовать шаблон декоратора для решения этой проблемы, чтобы ваша реализация оставалась чистой.

Создание интерфейса

public interface IMagic
{


    public void Method1()
    {
    }


    public void Method2()
    {
    }
}

Создание реализации

public class Magic : IMagic
{

    public void Method1()
    {
    }


    public void Method2()
    {
    }
}

Создать декоратор

public class MagicDecorator : IMagic
{
   private IMagic _magic;
   public MagicDecorator(IMagic magic)
   {
       _magic = magic;
   }

   private void BaseMethod()
   {
       // do something important
   }

    public void Method1()
    {
         BaseMethod();
         _magic.Method1();
    }


    public void Method2()
    {
        BaseMethod();
        _magic.Method2();
    }
}

Использование

var magic = new MagicDecorator(new Magic());
magic.Method1();
magic.Method2();
0 голосов
/ 25 октября 2016

Просто чтобы понять, почему следующая реализация не будет работать :

public class Magic{

private static Magic magic = new Magic();
public static Magic Instance{
  get
    {
   magic.BaseMethod();
    return magic;
    }
}

public void BaseMethod(){
}

//runs BaseMethod before being executed
public void Method1(){
}

//runs BaseMethod before being executed
public void Method2(){
}
}

В случае, если вы просто хотите удерживать объект Magic, метод будет вызываться случайным образом:

Magic m = Magic.Instance; //this will trigger unwanted call on BaseMethod

, а также, если кто-то захочет вызвать BaseMethod, он будет вызван дважды:

Magic.Instance.BaseMethod(); //two calls of the BaseMethod

который, конечно, имеет обходной путь, чтобы вернуть нежелательные объекты, используя get:

var unused = Magic.Instance;

Только для суммирования: Это невозможно (по крайней мере, пока) в C # .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...