2013-02-12 24 views
10

xem xét lớp generic này:C# generics - những gì đạt được bằng cách làm cho một lớp wrapper chung?

public class Request<TOperation> 
    where TOperation : IOperation 
{ 
    private TOperation _operation { get; set; } 

    public string Method { get { return _operation.Method; } } 

    public Request(TOperation operation) 
    { 
     _operation = operation; 
    } 
} 

gì lợi ích thực hiện các phiên bản generic trên cung cấp hơn này phiên bản không-generic dưới đây?

public class Request 
{ 
    private IOperation _operation { get; set; } 

    public string Method { get { return _operation.Method; } } 

    public Request(IOperation operation) 
    { 
     _operation = operation; 
    } 
} 

Giao diện IOperation là:

public interface IOperation 
{ 
    string Method { get; } 
} 

Trả lời

13

Với phiên bản generic một phương pháp có thể mất một tham số có kiểu Request<FooOperation>. Việc chuyển vào một thể hiện của Request<BarOperation> sẽ không hợp lệ.
Vì vậy, phiên bản chung cho phép các phương pháp để đảm bảo họ nhận được yêu cầu cho hoạt động chính xác.

+0

Gotcha - nói cách khác, nó cho phép bạn 'đóng' hoặc chỉ định kiểu 'Yêu cầu' hạn chế hơn khi được tiêu thụ, nhưng không cần phải tạo các đối tượng' Yêu cầu' tùy chỉnh cho các loại Hoạt động khác nhau .. – MalcomTucker

+0

@ MalcomTucker: Đúng vậy. –

3

Ví dụ, nếu bạn có

public class SubOperation : IOperation 
{ 
    // implementation ... 
} 

public class OtherSubOperation : IOperation 
{ 
    // implementation ... 
} 

Bạn có thể đảm bảo rằng các yêu cầu không bao giờ có thể tổ chức một mục OtherSubOperation, nhưng cả hai đều sẽ là IOperations hợp lệ.

4

Trong trường hợp bạn đã đưa ra ở trên, thật khó để nói những gì lợi ích bạn nhận được, nó sẽ phụ thuộc vào cách này được sử dụng trong cơ sở mã của bạn, nhưng hãy cân nhắc những điều sau đây:

public class Foo<T> 
    where T : IComparable 
{ 
    private T _inner { get; set; } 

    public Foo(T original) 
    { 
     _inner = original; 
    } 

    public bool IsGreaterThan<T>(T comp) 
    { 
     return _inner.CompareTo(comp) > 0; 
    } 
} 

chống lại

public class Foo    
    { 
     private IComparable _inner { get; set; } 

     public Foo(IComparable original) 
     { 
      _inner = original; 
     } 

     public bool IsGreaterThan(IComparable comp) 
     { 
      return _inner.CompareTo(comp) > 0; 
     } 
} 

Nếu sau đó bạn đã có một Foo<int>, có lẽ bạn sẽ không muốn so sánh nó với một Foo<string>, nhưng sẽ không có cách nào khóa đó xuống bằng cách sử dụng phiên bản không phải chung chung.

11

Ngoài tất cả các câu trả lời tốt khác, tôi sẽ thêm rằng phiên bản generic không mất boxing phạt nếu bạn xảy ra để xây dựng Request<T> với một T đó là một loại giá trị mà thực hiện IOperation. Các hộp phiên bản không chung chung mỗi lần.

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