2009-09-29 48 views
5

Giả sử đoạn mã sau (Vui lòng đọc câu hỏi của tôi trong các ý kiến ​​mã trong lớp cuối cùng):Làm thế nào để vượt qua một lớp Generic như một thông số để một constructor lớp phi generic

//This is my Generic Class 
public class ClientRequestInfo<K, V> 
{ 
    public string Id { get; set; } 
    private Dictionary<K, V> parameters; 

    public ClientRequestInfo() 
    { 
     parameters = new Dictionary<K, V>(); 
    } 

    public void Add(K key, V value) 
    { 
     parameters.Add(key, value); 
    } 
} 

public class ProcessParameters() 
{ 
    private void CreateRequestAlpha() 
    { 
     ClientRequestInfo<int, string> info = new ClientRequestInfo<int, string>(); 
     info.Add(1, "Hello"); 
     SynchRequest s = new SynchRequest(info); 
     s.Execute(); 
    } 
    private void CreateRequestBeta() 
    { 
     ClientRequestInfo<int, bool> info = new ClientRequestInfo<int, bool>(); 
     info.Add(1, true); 
     SynchRequest s = new SynchRequest(info); 
     s.Execute(); 
    } 
} 

public class SynchRequest 
{ 
    //What type should I put here? 
    //I could declare the class as SynchRequest<K, V> but I don't want 
    //To make this class generic. 
    private ClientRequestInfo<????,?????> info; 
    private SynchRequest(ClientRequestInfo<?????,?????> requestInfo) 
    { 
     //Is this possible? 
     this.info = requestInfo; 
    } 

    public void Execute() 
    {} 
} 
+0

Tại sao bạn không muốn sử dụng SynchRequest chung? – AnthonyWJones

+0

Bạn có thể nói về những gì bạn sẽ làm trong Execute() với thành viên thông tin không? Điều này có thể cung cấp một cơ sở cho một câu trả lời tương đương chức năng. – joshperry

+0

Vì lớp SynchRequest được gọi bởi các lớp khác của dự án và mục đích của SynchRequest là chạy dịch vụ và không cung cấp bất kỳ loại nào về thông tin khách hàng. Ngoài ra còn có các lớp học sử dụng SynchRequest và không chỉ định hoặc yêu cầu bất kỳ thông tin khách hàng nào. Vì vậy, không phải là cách tiếp cận tốt để làm cho lớp này chung chung. (SynchRequest có một hàm tạo rỗng) – Ioannis

Trả lời

7

Nếu bạn không muốn thực hiện SynchRequestInfo chung, bạn có thể tạo lớp cơ sở không chung chung cho ClientRequestInfo không? -

public abstract class ClientRequestInfo 
{ 
    public abstract void NonGenericMethod(); 
} 

public class ClientRequestInfo<K, V> : ClientRequestInfo 
{ 
    public override void NonGenericMethod() 
    { 
     // generic-specific implementation 
    } 
} 

Sau đó:

public class SynchRequest 
{ 
    private ClientRequestInfo info; 

    private SynchRequest(ClientRequestInfo requestInfo) 
    { 
     this.info = requestInfo; 
    } 

    public void Execute() 
    { 
     // ADDED: for example 
     info.NonGenericMethod(); 
    } 
} 
+0

Phương thức 'Execute' sẽ cần được khai báo trong lớp cơ sở nếu' CreateRequestAlpha' và 'CreateRequestBeta' có thể gọi nó. –

+0

'Execute' là một phần của' SynchRequest', không phải 'ClientRequestInfo'. –

2

Lớp có được chung nếu bạn muốn biến thành viên chung.

private ClientRequestInfo<????,?????> info; 

Là thành viên chung.

Bạn có thể sử dụng một lớp cơ sở không chung chung hoặc giao diện:

class ClientRequestInfo<K,Y> : IClientRequestInfo 

Nhưng trong ví dụ của bạn, ClientRequestInfo không có bất kỳ thành viên không chung chung, do các lớp giao diện/cơ sở sẽ được sản phẩm nào và có được đưa vào phiên bản chung chính xác để có ích.

1

Bạn có hai lựa chọn, nếu bạn muốn không làm cho SynchRequestInfo generic.

  1. Tạo một lớp cơ sở không chung chung, cả hai đều sử dụng nó.
  2. Cung cấp giao diện để sử dụng, chẳng hạn như ISynchInfo và yêu cầu lớp chung của bạn triển khai giao diện.

Trong trường hợp này, tôi thích cách tiếp cận giao diện hơn vì bạn có thể muốn đồng bộ hóa các loại khác (tách biệt với yêu cầu của khách hàng) trong tương lai.

1

Đặt ClientRequestInfo (K, V) triển khai giao diện ClientRequestInfo với các chức năng giao diện mà SynchRequest sẽ cần.

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