2012-11-27 30 views
6

Tôi đang tạo một trình đọc tệp phẳng chung trông giống như thế này.Tôi có thể bằng cách nào đó dọn dẹp này (lạm dụng?) Của Generics?

public class GenericReader<TComposite, THeader, TData, TTrailer> 
    where TComposite : GenericComposite<THeader, TData, TTrailer>, new() 
    where THeader : new() 
    where TData : new() 
    where TTrailer : new() 
{ 
    public TComposite Read() 
    { 
     var composite = new TComposite(); 

     composite.Header = new THeader(); 
     composite.Data = new TData(); 
     composite.Trailer = new TTrailer(); 

     return composite; 
    }   
} 

Nó có thể được tiêu thụ như vậy.

var reader = new GenericReader<Composite<Header, Data, Trailer>, Header, Data, Trailer>(); 

var composite = reader.Read(); 
Console.WriteLine(composite.Data.SomeProperty); 

Console.ReadLine(); 

Đây là các lớp được sử dụng.

public class Composite<THeader, TData, TTrailer> : GenericComposite<THeader, TData, TTrailer> 
{ 

} 

public class GenericComposite<THeader, TData, TTrailer> 
{ 
    public THeader Header { get; set; } 

    public TData Data { get; set; } 

    public TTrailer Trailer { get; set; } 
} 

public class Header { 
    public string SomeProperty { get { return "SomeProperty"; } } 
} 

public class Data { 
    public string SomeProperty { get { return "SomeProperty"; } } 
} 

public class Trailer { 
    public string SomeProperty { get { return "SomeProperty"; } } 
} 

Có cách nào tôi có thể xóa hoặc đóng gói thông tin loại chung đó trong GenericReader không? Tôi đang tìm một cặp mắt bổ sung để cho tôi thấy điều gì đó mà tôi đã bỏ lỡ. Chúng tôi đã làm điều gì đó với các giao diện trả lại và khiến người tiêu dùng thực hiện một dàn diễn viên, nhưng điều đó chỉ chuyển trách nhiệm đến vị trí sai trong quan điểm của tôi, cộng với một hình phạt nhỏ về hiệu suất.

Cảm ơn.

Chỉnh sửa: Tôi không cần TComposite, tôi chỉ có thể trả về GenericComposite. Làm thế nào tôi có thể bỏ lỡ điều đó?

public class GenericReader<THeader, TData, TTrailer> 
    where THeader : new() 
    where TData : new() 
    where TTrailer : new() 
{ 
    public GenericComposite<THeader, TData, TTrailer> Read() 
    { 
     var composite = new GenericComposite<THeader, TData, TTrailer>(); 

     composite.Header = new THeader(); 
     composite.Data = new TData(); 
     composite.Trailer = new TTrailer(); 

     return composite; 
    }   
} 

public class GenericComposite<THeader, TData, TTrailer> 
{ 
    public THeader Header { get; set; } 

    public TData Data { get; set; } 

    public TTrailer Trailer { get; set; } 
} 
+2

Bạn có thể muốn xem [mã đánh giá SE] (http://codereview.stackexchange.com/). Nó thực sự phù hợp hơn cho các nhiệm vụ đánh giá như thế này. – tmesser

+3

Tôi nghĩ câu hỏi này phù hợp với SO; nó không phải là một đánh giá mã quá nhiều như một câu hỏi về sự phụ thuộc lẫn nhau của các đối số kiểu chung chung (và kiểu hệ thống nói chuyện chắc chắn là trên chủ đề trong SO) và cách đơn giản hóa nó .. –

+0

Với tôi, GenericReader của bạn giống như một nhà máy sau đó là một loại chung chung, trừ khi tôi đang thiếu một cái gì đó. Âm thanh như bạn sẽ tạo ra nó chỉ để xử lý nó ngay sau đó. Vì vậy, có một lý do cho sự tồn tại của GenericReader bên cạnh việc cung cấp một Composite? Không thể hỗn hợp có một số phương pháp tĩnh để tạo ra các trường hợp của chính nó? – LightStriker

Trả lời

2

Không có cách nào để loại bỏ sự cần thiết cho các khai báo kiểu trên các ràng buộc chung mà bạn có.

Tuy nhiên, trường hợp sử dụng của bạn cho thấy rằng đây là hành vi phổ biến nhất:

var reader = new GenericReader<Composite<Header, Data, Trailer>, 
    Header, Data, Trailer>(); 

Nếu đây là trường hợp, nơi bạn có thể đưa ra giả định về tần số mà mô hình nào đó đang sử dụng, bạn có thể kế thừa một gõ (hoặc thiết lập các loại) từ các lớp chung với các định nghĩa kiểu đóng có thể được sử dụng dễ dàng hơn.

Trong trường hợp trên, bạn có thể cung cấp những lớp học cho các cơ sở, các trường hợp phổ biến nhất (ngoài các định nghĩa chung chung):

public class Composite : GenericComposite<Header, Data, Trailer> { } 

public class GenericReader : GenericReader< 
    Composite, Header, Data, Trailer> 
{ } 

Mà sau đó sẽ được sử dụng như sau:

var reader = new GenericReader(); 

var composite = reader.Read(); 

Console.WriteLine(composite.Data.SomeProperty); 

Console.ReadLine(); 

Bạn vẫn sẽ có các loại có các tham số chung để sử dụng cho các trường hợp chuyên sâu, nhưng đối với trường hợp sử dụng phổ biến (bạn xác định thông qua phân tích/kiến ​​thức tên miền), bạn có thể xác định những gì phổ biến nhất thiết lập các thông số kiểu để hỗ trợ.

+0

Đó là những gì tôi đang làm ngay bây giờ. Nên thêm nó vào câu hỏi. Thay vì giải pháp sane imo! – JefClaes

+0

@JefClaes Gần đây tôi có một tình huống mà tôi có ba tham số chung, và hai là trường hợp sử dụng thông thường, và tôi thấy rằng việc cung cấp các tham số được thừa kế với các tham số kiểu được xác định trước (những gì tôi đề nghị) là tốt nhất cho tôi. Serendipitous, có lẽ. – casperOne

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