Run a method before all methods of a class

前端 未结 8 2113
孤街浪徒
孤街浪徒 2020-12-06 15:51

Is it possible to do that in C# 3 or 4? Maybe with some reflection?

class Magic
{

    [RunBeforeAll]
    public void BaseMethod()
    {
    }

    //runs Ba         


        
相关标签:
8条回答
  • 2020-12-06 16:23

    You can't do this automatically in C# - you should probably be looking at AOP, e.g. with PostSharp.

    0 讨论(0)
  • 2020-12-06 16:24

    Just to make a thing clear why the following implementation won't work:

    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(){
    }
    }
    

    in the case you just want to hold a Magic object, the method will be randomly called:

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

    and also if one will want to call the BaseMethod, it will be called twice:

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

    which of course have a workaround, to return unwanted objects using get:

    var unused = Magic.Instance;
    

    Only to summarize: This is not possible (at least yet) in C#.

    0 讨论(0)
  • 2020-12-06 16:30

    There is an alternate solution for this, make Magic a singleton and put your code on the getter of the static instance. That's what i did.

    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(){
    }
    }
    
    0 讨论(0)
  • 2020-12-06 16:32

    Yes, you can! with a static constructor, it will run once before the class is referenced and you can do what you like in it.

    Like this:

    public class Magic{
    
    static Magic()
    {
        BaseMethod();
    }
    
    public void BaseMethod(){
    }
    
    //runs BaseMethod before being executed
    public void Method1(){
    }
    
    //runs BaseMethod before being executed
    public void Method2(){
    }
    }
    

    Here's the Microsoft doc:

    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/static-constructors

    0 讨论(0)
  • 2020-12-06 16:33

    What you want can be done with AOP - some links to .NET C# AOP frameworks:

    • http://www.postsharp.org/
    • http://www.castleproject.org/dynamicproxy/index.html
    • http://www.springframework.net/docs/1.2.0-M1/reference/html/aop.html
    0 讨论(0)
  • 2020-12-06 16:36

    I've recently had cause to do this. I'll spare you the probably boring details of my use-case, except to state that I want the method DoThisFirst to run before the specific method I'm calling. Still learning C# so probably not the best way to do it...

    using System;
    
    namespace ConsoleApp1
    {
        class Class1
        {
            public enum MethodToCall
            {
                Method2,
                Method3
            }
    
            public delegate void MyDelegate(int number = 0, bool doThis = false, double longitude = 32.11);
    
            public static void DoThisFirst(int number, bool doThis, double longitude)
            {
                Console.WriteLine("DoThisFirst has been called.");
            }
    
            public static void DoSomethingElse(int number, bool doThis, double longitude)
            {
                Console.WriteLine("DoSomethingElse has been called.");
            }
    
            public static void DoAnotherThing(int number, bool doThis, double longitude)
            {
                Console.WriteLine("DoAnotherThing has been called.");
            }
    
            public static void Main()
            {
                void Action(MethodToCall methodToCall)
                {
                    MyDelegate myDel;
    
                    myDel = new MyDelegate(DoThisFirst);
    
                    switch (methodToCall)
                    {
                        case MethodToCall.Method2:
                            myDel += DoSomethingElse;
                            break;
                        case MethodToCall.Method3:
                            myDel += DoAnotherThing;
                            break;
                    }
    
                    myDel.Invoke();
                }
    
                Action(MethodToCall.Method3);
    
                Console.ReadKey();
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题