2017-04-06 115 views
5

我正在研究C#控制台应用程序。我的目标是创建一个名为GroupEntity的对象,最好是非泛型类型的对象。在非泛型类C中包装泛型类#

此GroupEntity对象内部将是一个'AttributeFilter'对象的列表,其中包含通用类型的对象,其中包含Active Directory中的用户对象上的属性名称以及这些用户对象的可能值。我希望AttributeFilter对象采用通用类型的原因是因为AD中用户对象的某些属性是字符串,有些是int32,有些是int64等。

这里是我的类(我剪掉了构造函数等以节省空间)

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 
} 

这里是GroupEntity类。注意我有一个

List<AttributeFilter<T>> 

字段。问题是我不知道T将是什么,直到我运行的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; 
    } 

}

现在我用Program.cs的初始化及测试...

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); 

} 

那么如何我可以在没有通用参数的情况下编写我的GroupEntity类,因此我可以在其中包含各种类型的AttributeFilter<T>。所以例如,我可以容纳AttributeFilter<int>AttributeFilter<string>AttributeFilter<long>

我似乎无法弄清楚这个问题。

+2

创建'AttributeFilter'的非泛型'AttributeFilter'基类,并引用GroupEntity中的基类。 –

+0

你的系统中的GroupEntity对象的实际用例是什么?可以有三个字段('List >','List >','List >')是一个解决方案吗?否则,如果你在编译时不知道类型参数,泛型很可能不是要走的路。 –

+0

这些只是三个例子。基本上我试图为AD用户属性中使用的任何数据类型创建AttributeFilter 。字符串,long和int32是常见的。但是我也看到了string [],byte [],DateTime等等。所以我将不得不创造所有这些。 – user5078178

回答

2

或多或少你不能。

与不同类型的实例化的通用类型的具有彼此没有关系(即AttributeFilter<long>AttributeFilter<int>没有得到任何共同的基类 - 它们可用作ExceptionHttpClient作为目前存在的)。因此,没有办法通过强大的输入将这些类型的实例放入单个集合中。

标准解决方案 - 为您的AttributeFilter<T>类型使用非通用基类或接口。或者 - 将它们存储为object的集合,并丢失所有类型的安全性,或者可能收集dynamic,它们至少会给你机会调用方法(以反思为代价)。

+0

谢谢Alixei Lenenkov和Michael Liu的建议。 – user5078178