2017-04-06 14 views
5

Tôi đang làm việc trên ứng dụng bảng điều khiển C#. Mục tiêu của tôi là tạo ra một đối tượng được gọi là GroupEntity, tốt hơn là loại không chung chung.Gói một lớp Chung bên trong một lớp không thuộc loại Chung C#

Bên trong nhóm đối tượng này đối tượng sẽ là danh sách đối tượng 'AttributeFilter' chứa đối tượng Generic type giữ tên thuộc tính trên đối tượng người dùng trong Active Directory và giá trị có thể có của các đối tượng người dùng đó. Lý do tôi muốn đối tượng AttributeFilter lấy một kiểu generic là vì một số thuộc tính trên các đối tượng người dùng trong AD là chuỗi, một số là int32, một số là int64, v.v.

Đây là các lớp của tôi. để tiết kiệm không gian tại đây)

public class AttributeFilter<T> : IEqualityComparer<AttributeFilter<T>> 
     { 
      private string _attributeName;  
      private T _attributeValue;   
      private List<T> _attributeValues { get; set; } 

      public AttributeFilter(string attributeName) 
      { 
       AttributeName = attributeName; 
       _attributeValues = new List<T>(); 
      } 

      public void AddValues(T attributeValue) 
      { 
       AttributeValue = attributeValue; 
       if (!_attributeValues.Contains(AttributeValue)) 
       { 
        _attributeValues.Add(AttributeValue); 
       } 
      } 

// Ive cut out the getter setter etc that is not relevant 
} 

Đây là lớp GroupEntity. Lưu ý rằng tôi có một trường hợp

List<AttributeFilter<T>> 

. Vấn đề là tôi không biết những gì T sẽ được cho đến khi tôi chạy program.cs

public class GroupEntity<T> 
{ 
    private string _groupName; 

    // because I want to a have a List<AttributeFilter<T>>, but I dont really want this here. because of program.cs when I initialise a new GroupEntity<> I have to tell it what type. I wont know. The type could be int32, string, long or whatever. 
    private List<AttributeFilter<T>> _filters; 

    public void AddFilters(AttributeFilter<T> attributeFilter) 
    { 
     if (!_filters.Contains(attributeFilter, attributeFilter)) 
     { 
      _filters.Add(attributeFilter); 
     } 
    } 

    public GroupEntity() 
    { 
     _filters = new List<AttributeFilter<T>>(); 
    } 

    public GroupEntity(string groupName) : this() 
    { 
     _groupName = groupName; 
    } 

}

Bây giờ tôi sử dụng program.cs để khởi và thử nghiệm ...

class Program 
    { 
     static void Main(string[] args) 
     { 

      // Create AttributeFilter object for user attribute: EYAccountType 
      var at1 = new AttributeFilter<string>("EYAccountType"); 
      at1.AddValues("02");    
      at1.AddValues("03"); 
      at1.AddValues("04"); 
      at1.AddValues("05"); 


      // try adding anothr AtributeFilter with same name. 
      var at3 = new AttributeFilter<string>("EYAccountType1"); 
      at3.AddValues("06"); 
      at3.AddValues("07"); 



      // Create AttributeFilter object for user attribute: userAccountControl 
      var at2 = new AttributeFilter<int>("userAccountControl"); 
      at2.AddValues(512); 
      at2.AddValues(544); 
      at2.AddValues(546); 
      at2.AddValues(4096); 


      // Now create a GroupEntity object 
      var group1 = new GroupEntity<string>("My_First_AD_Group_Name"); 


      // Try adding the above two AttributeFilter objects we created to the GroupEntity object. 
      group1.AddFilters(at1); 
      group1.AddFilters(at3); 

      // This is the problem. I know why this is happening. because I initialised the var group1 = new GroupEntity<string>. So it wont accept at2 because at2 is taking in int. 
      //group1.AddFilters(at2); 

} 

Vậy làm thế nào Tôi có thể viết lớp GroupEntity của tôi mà không có một tham số chung vì vậy tôi có thể giữ các loại khác nhau của AttributeFilter<T> bên trong nó. Ví dụ: tôi có thể giữ AttributeFilter<int>AttributeFilter<string>AttributeFilter<long>

Tôi dường như không tìm ra được vấn đề này.

+2

Tạo lớp cơ sở không thuộc tính 'AttributeFilter' của' AttributeFilter 'và tham chiếu lớp cơ sở trong GroupEntity. –

+0

Trường hợp sử dụng thực tế cho đối tượng 'GroupEntity' trong hệ thống của bạn là gì? Có thể có ba trường ('List >', 'List >', 'List >') là một giải pháp? Nếu không, nếu bạn không biết tham số kiểu tại thời gian biên dịch, generics có lẽ không phải là cách để đi. –

+0

Đó chỉ là ba ví dụ. Về cơ bản tôi đang cố gắng để tạo ra một AttributeFilter cho bất kỳ loại dữ liệu được sử dụng trong thuộc tính người dùng AD. chuỗi, dài và int32 là phổ biến. Nhưng tôi cũng thấy chuỗi [], byte [], DateTime và một vài chi tiết khác. Vì vậy, tôi sẽ phải tạo ra tất cả những thứ đó. – user5078178

Trả lời

2

Ít hoặc nhiều bạn không thể.

loại Generic instantiated với các loại khác nhau không có mối quan hệ với nhau (ví dụ: AttributeFilter<long>AttributeFilter<int> không nhận được bất kỳ lớp cơ sở chung - họ là như differnet như ExceptionHttpClient). Vì vậy, không có cách nào để đưa các thể loại như vậy vào bộ sưu tập duy nhất với cách gõ mạnh.

Giải pháp tiêu chuẩn - sử dụng loại cơ sở không chung chung hoặc giao diện cho loại AttributeFilter<T> của bạn. Cách khác - lưu trữ chúng như là bộ sưu tập của object và mất tất cả các loại an toàn, hoặc có thể thu thập dynamic mà ít nhất là cung cấp cho bạn cơ hội để gọi phương pháp (với chi phí phản ánh).

+0

Cảm ơn bạn Alixei Lenenkov và Michael Liu vì những gợi ý của bạn. – user5078178

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