2009-03-20 27 views
5

Tôi đang cố gắng tạo một biểu mẫu sẽ tạo hiệu ứng gì đó trong khi xử lý một tác vụ cụ thể (được chuyển giao làm đại biểu cho hàm tạo). Nó hoạt động tốt, nhưng vấn đề tôi gặp phải là tôi không thể khởi tạo một bản sao của lớp chung của tôi nếu phương thức cụ thể mà tôi muốn thực hiện có một kiểu trả về void.bỏ dấu trống cho một lớp chung

Tôi hiểu rằng điều này là do thiết kế và tất cả, nhưng tôi tự hỏi nếu có một cách giải quyết được biết đến cho các tình huống như thế này.

Nếu nó giúp ở tất cả các cửa sổ của tôi dưới hình thức trông như vậy (tỉa cho ngắn gọn):

public partial class operatingWindow<T> : Form 
{ 
    public delegate T Operation(); 
    private Operation m_Operation; 

    private T m_ReturnValue; 
    public T ValueReturned { get { return m_ReturnValue; } } 

    public operatingWindow(Operation operation) { /*...*/ } 
} 

Và tôi gọi nó là thích:

operatingWindow<int> processing = new operatingWindow<int>(new operatingWindow<int>.Operation(this.doStuff)); 
processing.ShowDialog(); 

// ... 
private int doStuff() 
{ 
    Thread.Sleep(3000); 

    return 0; 
} 

Trả lời

4

Tôi sẽ suy nghĩ lại về thiết kế của bạn một chút.

Nếu bạn triển khai xử lý trong một lớp cơ sở, bạn có thể phân lớp nó bằng 2 lựa chọn thay thế gần như có thể hoán đổi cho nhau.

Giá trị đầu tiên có thể giống như của bạn, trong đó cần một thao tác trả về một giá trị. (Tôi sẽ làm lại điều này để sử dụng Func<T> thay vì có loại đại biểu của riêng bạn, mặc dù.

Thứ hai chỉ có thể thực hiện Hành động đơn giản và không cung cấp giá trị trả lại. .. nhưng cung cấp một cách khác nhau làm việc bạn cũng có thể chuyển thông tin này ra với các phương pháp khác sử dụng các lớp cơ sở, trong đó sẽ cung cấp rất nhiều tính linh hoạt

với phương pháp này, bạn có thể gọi đây như:

private void DoSleep() 
{ 
    Thread.CurrentThread.Sleep(5000); 
} 
private int ReturnSleep() 
{ 
    Thread.CurrentThread.Sleep(5000); 
    return 5000; 
} 
... 
{ 
    var actionWindow = new OperatingWindowAction(this.DoSleep); 
    actionWindow.Execute(); 
    var funcWindow = new OperatingWindowFunc<int>(this.ReturnSleep); 
    funcWindow.Execute(); 
    int result = funcWindow.Result; 
} 

Điều này trông giống như sau:

public abstract partial class OperatingWindowBase : Form 
{ 
    public void Execute() 
    { 
     // call this.OnExecute(); asyncronously so you can animate 
    } 
    protected abstract void OnExecute(); 
} 

public class OperatingWindowFunc<T> : OperatingWindowBase 
{ 
    Func<T> operation; 
    public T Result { get; private set; } 
    public OperatingWindowFunc<T>(Func<T> operation) 
    { 
     this.operation = operation; 
    } 
    protected override OnExecute() 
    { 
     this.Result = operation(); 
    } 
} 

public class OperatingWindowAction 
{ 
    Action operation; 
    public OperatingWindow(Action operation) 
    { 
     this.operation = operation; 
    } 
    protected override OnExecute() 
    { 
     operation(); 
    } 
} 
6

Không, bạn sẽ cần phải tạo ra một quá tải để làm điều đó.

ví dụ:

public operatingWindow(Action action) 
{ 
    m_Operation=() => { action(); return null; } 
} 

Ngoài ra, bạn không cần phải xác định đại biểu của riêng bạn, bạn có thể sử dụng Func<T> và hành động.

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