2012-02-08 25 views
16

Có thể thực hiện điều đó trong C# 3 hoặc 4 không? Có lẽ với một số phản ánh?Chạy phương pháp trước tất cả các phương thức của một lớp

class Magic 
{ 

    [RunBeforeAll] 
    public void BaseMethod() 
    { 
    } 

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

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

EDIT

Có một giải pháp thay thế cho việc này, hãy Magic một singleton và đưa code của bạn trên getter của instance tĩnh. Đó là những gì tôi đã làm:

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

Làm thế nào về một hàm tạo? – JConstantine

+1

Sử dụng một hàm tạo là không có giải pháp, bởi vì nếu tôi được thực hiện, nói rằng, hai phương pháp của một ví dụ, tôi chỉ nhận được basemethod để chạy một lần. Cũng rất không thích hợp cho các trường hợp tĩnh. –

+0

Bạn có thể thực hiện điều này bằng cách sử dụng 'dynamic' và triển khai [' IDynamicMetaObjectProvider'] (http://msdn.microsoft.com/en-us/library/system.dynamic.idynamicmetaobjectprovider.aspx). Điều này sẽ cho phép bạn chạy mã của riêng bạn trong quá trình ràng buộc, điều này xảy ra trước khi một phương thức được thực hiện. Lưu ý: Đề xuất này được cung cấp như một sự tò mò. Nó không thực sự là một cách tốt để giải quyết vấn đề của bạn. – Brian

Trả lời

7

Có một giải pháp thay thế cho việc này , làm cho Magic một singleton và đặt mã của bạn trên getter của thể hiện tĩnh. Đó là những gì tôi đã làm.

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

điều này có vẻ thú vị nhưng nó sẽ không hoạt động. trường riêng không được khởi tạo. Nếu bạn giải thích làm thế nào để bắt đầu lĩnh vực ma thuật, điều này có thể làm việc. – hakan

+0

Bạn có thể thực hiện một bước khởi đầu lười biếng, nghĩa là kiểm tra nếu null trước khi accesing (thường chỉ là lần đầu tiên). Nếu có, hãy lập trình nó. – CBinet

8

Bạn không thể thực hiện điều này tự động trong C# - có thể bạn nên xem AOP, ví dụ: với PostSharp.

+0

Tôi có một số nghi ngờ về AOP như một giải pháp cho điều này, bởi vì tôi tin rằng OP muốn thực hiện một phương thức trước khi một phương thức gọi và sau đó không "sử dụng" khía cạnh nữa. Có thể một số cờ thể hiện lớp như _Initialized_ và nếu nó là _true_, không làm gì trong khía cạnh? –

+0

@ MatíasFidemraizer: Tôi không tin như vậy, dựa trên một bình luận sau: "Sử dụng một constructor là không có giải pháp, bởi vì nếu tôi đã thực hiện, nói rằng, hai phương pháp của một ví dụ, tôi chỉ nhận được basemethod để chạy một lần "- vì vậy tôi tin rằng OP muốn phương thức được chạy trên * mọi * lời gọi. –

+0

Vâng, sau đó, PostSharp (hoặc bất kỳ khung AOP khác) là giải pháp của chúng tôi!Nhận xét này được công bố sau những nghi ngờ của tôi. Và, tôi tin rằng đây là câu trả lời đúng, bởi vì _IL woven_ tốt hơn proxying cho trường hợp này. –

0

Chỉ cần để thực hiện một điều rõ ràng lý do tại sao việc thực hiện sau sẽ không làm việc:

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

trong trường hợp bạn chỉ muốn giữ một đối tượng Magic, phương pháp này sẽ được gọi là ngẫu nhiên:

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

và nếu người khác muốn gọi số BaseMethod, số này sẽ được gọi hai lần:

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

trong đó tất nhiên có một cách giải quyết, để trở về đối tượng không mong muốn sử dụng get:

var unused = Magic.Instance; 

Chỉ để tóm tắt: này là không thể (ít nhất là chưa) trong C#.

Các vấn đề liên quan