2012-08-16 30 views
14

Có cách nào tốt hơn để viết điều này không? Là một lớp có lẽ, thay vì hai.Các loại chung tùy chọn

using System; 

namespace SnippetTool.Repositories 
{ 
    public abstract class ARepository<TProvider> where TProvider : class 
    { 
     protected TProvider Provider { get; set; } 

     protected ARepository(TProvider provider) 
     { 
      if (provider == null) 
       throw new ArgumentNullException("provider"); 

      Provider = provider; 
     } 
    } 

    public abstract class ARepository<TProvider, TValidator> : ARepository<TProvider> where TProvider : class where TValidator : class 
    { 
     protected TValidator Validator { get; set; } 

     protected ARepository(TProvider provider, TValidator validator) : base(provider) 
     { 
      Validator = validator; 
     } 
    } 
} 
+4

Phụ thuộc vào những gì bạn muốn đạt được – Magnus

+0

Tôi muốn đạt được TValidator là tùy chọn. – CaffGeek

+1

Wow ... 3 phiếu bầu? Giải thích ZERO. – CaffGeek

Trả lời

11

Tôi không nghĩ rằng bạn có thể làm điều đó như một lớp, hiện tại, những gì tôi cố gắng làm trong trường hợp này là tạo ra lớp học chung nhất (một trong những người có chung nhất) để có tất cả logic, sau đó làm cho những cái cụ thể hơn là các lớp con mặc định các loại đó.

Ví dụ, giả sử chúng ta đang viết một dịch mà dịch từ một loại giá trị khác, vì vậy giống như một Dictionary mà còn có giá trị mặc định vv

Chúng ta có thể định nghĩa này như:

public class Translator<TKey, TValue, TDictionary> where TDictionary : IDictionary<TKey, TValue>, new(); 
{ 
    private IDictionary<TKey, TValue> _map = new TDictionary(); 
    ... 
} 

Đây là trường hợp chung của tôi, có thể có bất kỳ thực hiện IDictionary, nhưng nói rằng chúng ta muốn có một phiên bản đơn giản mà luôn luôn sử dụng Dictionary nếu không quy định, chúng ta có thể làm:

public class Translator<TKey, TValue> : Translator<TKey, TValue, Dictionary<TKey, TValue>> 
{ 
    // all this does is pass on the "default" for TDictionary... 
} 

Bằng cách này, tôi có thể làm:

// uses Dictionary<int, string> 
var generic = new Translator<int, string>(); 

// uses SortedDictionary instead 
var specific = new Translator<int, string, SortedDictioanry<int, string>>(); 

Vì vậy, trong trường hợp của bạn, có lẽ chung của bạn luôn luôn có một tài sản TValidator, nhưng nó mặc định (có thể để luôn trở true ở dạng generic nhất của bạn?

Ví dụ, có thể bạn có một định nghĩa của một mặc định validator (nói gọi DefaultValidator), bạn có thể đảo ngược các định nghĩa của bạn để chung chung hơn (một trong đó có các tham số kiểu chung chung hơn) có tất cả các logic và bất kỳ chuyên ngành (ít thông số loại) chỉ là lớp con rằng mặc những loại bổ sung:

using System; 

namespace SnippetTool.Repositories 
{ 
    public class DefaultValidator 
    { 
     // whatever your "default" validation is, may just return true... 
    } 

    public abstract class ARepository<TProvider> : ARepository<TProvider, DefaultValidator> 
     where TProvider : class 
    { 
     protected ARepository(TProvider provider) : base(provider, new DefaultValidator()); 
     { 
     } 

     // needs no new logic, just any specialized constructors... 
    } 

    public abstract class ARepository<TProvider, TValidator> 
     where TProvider : class 
     where TValidator : class 
    { 
     public TValidator Validator { get; set; } 

     protected ARepository(TProvider provider, TValidator validator) 
     { 
      Provider = provider; 
      Validator = validator; 
     } 

     // all the logic goes here... 
    } 
} 

CẬP NHẬT: Vâng, dựa trên nhận xét của bạn, nếu TValidator là một add-on (và không phải cái gì vỡ), sau đó phân lớp nó như bạn đã làm là thích hợp.

+0

Vấn đề là, tôi không muốn một TValidator ở tất cả trong một số trường hợp, không có mặc định, tôi chỉ không muốn nó. Nhưng tôi luôn cần một TProvider. – CaffGeek

+1

@Chad: Sau đó, mã của bạn là một cách tốt để làm điều đó, lời khuyên duy nhất của tôi sẽ là cố gắng làm cho một trong các lớp học càng nhẹ càng tốt để tránh logic trùng lặp. –

+0

Cảm ơn, điều đó đã xác nhận những gì tôi nghĩ. – CaffGeek

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