2010-01-15 47 views
14

Tôi muốn cho phép gọi phương thức từ các phương thức cụ thể. Hãy xem mã bên dưới.Cách cấm gọi phương thức C#

private static void TargetMethod() 
    { 
    } 

    private static void ForbiddenMethod() 
    { 
    TargetMethod(); 
    } 

    private static void AllowedMethod() 
    { 
    TargetMethod(); 
    } 

Tôi chỉ cần AllowedMethod mới có thể gọi TargetMethod. Làm thế nào để làm điều đó bằng cách sử dụng các lớp học từ System.Security.Permissions?

Đã cập nhật: Cảm ơn câu trả lời của bạn, nhưng tôi không muốn tranh luận về thiết kế ứng dụng của tôi. Tôi chỉ muốn biết là nó có thể làm điều đó bằng cách sử dụng bảo mật .net hay không?

+5

Nếu đó là riêng tư, tại sao lại quan trọng? –

+15

Câu hỏi này được bỏ phiếu lên 9 lần chỉ trong 6 phút? – shoosh

+3

Bạn đang cố gắng bảo vệ bạn khỏi chính mình? Khác hơn là tôi không thể tưởng tượng việc sử dụng cho điều này. – Skurmedel

Trả lời

4

CAS không thể thực hiện điều này nếu mã đang hoạt động hoàn toàn.

Nếu mã đang thực thi trong Full Trust (ví dụ: ứng dụng cục bộ thông thường, không phải ứng dụng Silverlight hoặc thứ gì đó chạy từ mạng), thì tất cả.NET CAS kiểm tra hoàn toàn bỏ qua; bất kỳ thuộc tính bảo mật nào đều bị bỏ qua.

CAS chỉ cần truy cập ngăn xếp để xác định quyền, và bạn cũng có thể làm điều đó, như Darin đã chỉ ra trước đó bằng cách chỉ kiểm tra StackTrace.

8

Tôi tin bạn nên cố gắng cấu trúc mã của bạn trong các lớp học đầy ý nghĩa và sử dụng công cụ sửa đổi truy cập chuẩn (private, protected, public, internal). Có lý do cụ thể nào khiến điều này không giải quyết được vấn đề của bạn không?

Cách thay thế duy nhất tôi có thể nghĩ đến, sẽ liên quan đến việc vượt qua ngăn xếp cuộc gọi từ bên trong callee, nhưng điều đó có khả năng sẽ tạo ra sự lộn xộn của mã và hiệu suất tối ưu.

4

Tôi không chắc chắn nếu điều này có thể đạt được với System.Security.Permissions, nhưng bên trong TargetMethod bạn có thể nhận người gọi và hành động phù hợp:

StackTrace stackTrace = new StackTrace(); 
Console.WriteLine(stackTrace.GetFrame(1).GetMethod().Name); 
+0

+1; và dường như có thể đóng gói bằng cách thực thi 'CodeAccessPermission' –

+0

vâng, tôi biết về nó. Nhưng tôi thú vị làm thế nào để làm điều đó với các thuộc tính bảo mật. – alga

+0

Kỹ thuật này là chậm và có khả năng mong manh: Phương pháp nội tuyến bởi JITter có thể khiến cuộc gọi 'GetMethod' trả về kết quả không mong muốn. (Bạn có thể, tất nhiên, nói với JITter không trực tiếp, như trong câu trả lời của Thorarin.) – LukeH

24

Bạn có thể giải quyết vấn sử dụng thiết kế hướng đối tượng bình thường này. Di chuyển AllowedMethod để một lớp mới và làm ForbiddenMethod một phương pháp riêng của lớp đó:

public class MyClass 
{ 
    public void AllowedMethod() { // ... } 

    private void TargetMethod() { // ... } 
} 

AllowedMethod có quyền truy cập cho các thành viên tư nhân, nhưng không một ai có.

6

Bạn có thể kiểm tra ngăn xếp cuộc gọi để thực hiện việc này, nhưng nó khá chậm. Tôi sẽ không khuyên bạn nên nó nếu nó có thể tránh được.

Nếu bạn vẫn muốn thực hiện điều này, bạn cũng cần phải cẩn thận để tránh phương thức nội tuyến hoặc mã của bạn đột nhiên có thể ngừng hoạt động trong Bản dựng bản phát hành.

[MethodImpl(MethodImplOptions.NoInlining)] 
private static void TargetMethod() 
{ 
    StackFrame fr = new StackFrame(1, false); 
    Console.WriteLine(fr.GetMethod().Name); 
} 

Theo như tôi biết, không có thuộc tính out-of-the-box để làm điều này.

2

Bằng cách sử dụng Thuộc tính, bạn có thể giải quyết vấn đề này.

Sử dụng Attributs có điều kiện.

Ở phía trên

#define "Show" 


    public void TargetMethod() 
    { 
     //Code 
    } 
    [ Conditional("Hidden")] 
    public void HiddenMethod() 
    { 
     TargetMethod() 
    } 
[ Conditional("Show")] 
    public void AllowMethod() 
    { 
     TargetMethod() 
    } 

Một trong methos của bạn sẽ được gọi.

+2

Cũng loại bỏ 'HiddenMethod' hoàn toàn. Tôi nghĩ những gì alga muốn, là chọn một vài phương thức được phép gọi là 'TargetMethod' trong khi từ chối * tất cả những thứ khác *, bao gồm cả các phương thức trong mã của bên thứ 3, để gọi' TargetMethod'. Trình biên dịch có điều kiện sẽ không giúp bạn đạt được điều này ^^ –

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