2009-03-20 30 views
15

Tôi muốn có một thư viện sẽ có một hàm trong đó chấp nhận một đối tượng cho tham số của nó.Gọi lại trong C#

Với đối tượng này, tôi muốn có thể gọi một hàm được chỉ định khi X kết thúc. Chức năng sẽ được gọi là được chỉ định bởi người gọi, và X sẽ được thực hiện và giám sát bởi thư viện.

Tôi làm cách nào để thực hiện việc này?

Để tham khảo, tôi đang sử dụng C# và .NET 3.5

+0

Tôi nghi ngờ câu trả lời của bạn chứa các biến số, sự kiện hoặc cả hai. Tuy nhiên, sau khi đọc câu hỏi của bạn một vài lần, tôi không thể quấn đầu của tôi xung quanh những gì bạn đang yêu cầu. – Brian

+1

Đây là mẫu http://blog.jerrynixon.com/2011/11/there-are-lots-of-things-that-take-long.html –

Trả lời

38

Cung cấp một đại biểu và sử dụng một đại biểu vô danh hoặc Lambda biểu

public static void DoWork(Action processAction) 
{ 
    // do work 
    if (processAction != null) 
    processAction(); 
} 

public static void Main() 
{ 
    // using anonymous delegate 
    DoWork(delegate() { Console.WriteLine("Completed"); }); 

    // using Lambda 
    DoWork(() => Console.WriteLine("Completed")); 
} 

Hoặc sử dụng một giao diện

public interface IObjectWithX 
{ 
    void X(); 
} 

public class MyObjectWithX : IObjectWithX 
{ 
    public void X() 
    { 
    // do something 
    } 
} 

public class ActionClass 
{ 
    public static void DoWork(IObjectWithX handlerObject) 
    { 
    // do work 
    handlerObject.X(); 
    } 
} 

public static void Main() 
{ 
    var obj = new MyObjectWithX() 
    ActionClass.DoWork(obj); 
} 
1

Đối tượng được đề cập sẽ cần triển khai giao diện do bạn cung cấp. Lấy giao diện làm tham số và sau đó bạn có thể gọi bất kỳ phương thức nào mà giao diện hiển thị. Nếu không, bạn không có cách nào biết được đối tượng có khả năng làm gì. Điều đó, hoặc bạn có thể lấy một đại biểu như một tham số và gọi đó.

+0

Điều này là chính xác. – plinth

6

Âm thanh như một công thức hoàn hảo cho các đại biểu - đặc biệt, các cuộc gọi lại với đại biểu chính xác cách xử lý này trong mẫu không đồng bộ trong .NET.

Người gọi thường sẽ chuyển cho bạn một số trạng thái và đại biểu, và bạn lưu trữ cả hai trạng thái này trong bất kỳ bối cảnh nào, sau đó gọi cho đại biểu chuyển trạng thái đó và bất kỳ kết quả nào bạn có thể có.

Bạn có thể đặt trạng thái chỉ là object hoặc có khả năng sử dụng đại biểu chung và đưa ra loại trạng thái thích hợp, ví dụ:

public delegate void Callback<T>(T state, OperationResult result) 

Sau đó:

public void DoSomeOperation(int otherParameterForWhateverReason, 
          Callback<T> callback, T state) 

Như bạn đang sử dụng .NET 3.5 bạn có thể muốn sử dụng Func<...>Action<...> loại đại biểu hiện có, nhưng bạn có thể thấy nó làm cho nó rõ ràng hơn để khai báo của riêng bạn. (Tên có thể làm cho nó rõ ràng hơn những gì bạn đang sử dụng nó.)

+2

Tôi đề nghị bạn đọc lên các đại biểu sau đó (và Generics, có khả năng). Bài viết của tôi về đại biểu và evvents là tại http://pobox.com/~skeet/csharp/events.html –

1

Có lý do gì để thư viện của bạn không cung cấp sự kiện công khai khi hoạt động hoàn tất? Sau đó, người gọi chỉ có thể đăng ký để xử lý sự kiện và bạn không phải lo lắng về việc đi qua các đối tượng hoặc đại biểu.

Đối tượng triển khai giao diện mà bạn đã cung cấp sẽ hoạt động, nhưng dường như có nhiều cách tiếp cận Java hơn phương pháp .NET. Sự kiện dường như sạch hơn một chút với tôi.

+0

Tôi không biết cách thực hiện các sự kiện ... – Malfist

+0

Xem http://pobox.com/~skeet/csharp/events.html để tìm hiểu về các sự kiện. Họ có thể hoặc có thể không phù hợp với hoàn cảnh của bạn, nhưng họ đáng biết. –

-2

Bạn có thể sử dụng System.Action sẵn trong C# .NET cho các chức năng gọi lại. Vui lòng kiểm tra ví dụ mẫu này:

//Say you are calling some FUNC1 that has the tight while loop and you need to 
    //get updates on what percentage the updates have been done. 
    private void ExecuteUpdates() 
    { 
     Func1(Info => { lblUpdInfo.Text = Info; }); 
    } 

    //Now Func1 would keep calling back the Action specified in the argument 
    //This System.Action can be returned for any type by passing the Type as the template. 
    //This example is returning string. 
    private void Func1(System.Action<string> UpdateInfo) 
    { 
     int nCount = 0; 
     while (nCount < 100) 
     { 
      nCount++; 
      if (UpdateInfo != null) UpdateInfo("Counter: " + nCount.ToString()); 
      //System.Threading.Thread.Sleep(1000); 
     } 
    } 
+0

Đó không phải là một thay thế cho một cuộc gọi lại; rằng ** là ** một cuộc gọi lại. – Servy

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