2013-01-08 107 views
1

我有2個列表,我需要檢查傳遞給通用包裝器的公共對象。如何檢查2個通用列表之間的公共對象

第一個列表(selList)是一個鍵入的實體列表。該列表中的ID字段根據正在創建的列表的基類型而不同。

第二個列表(masterList)是一個匿名IList,我知道它有2個屬性{ID,DESC} - ID(可以是int或字符串)和description(字符串)。我可以在此列表中獲取ID屬性的值。

我想返回主列表的擴展名,其中有一個布爾字段,指示主列表中的項目是否包含在selList中。

我在想我是沿着Visitor模式行的某個地方。

public class SelectionCriteria<T> : where T : class 
{ 
    public IList<T> EligibleList { get; private set; } 
    public IList LookupList { get; private set; } 
} 
LookupList = new List<object> 
       { 
        new { ID = "fid", DESC = "Record 1"}, 
        new { ID = "Record2", DESC = "Record 2"}, 
        new { ID = "Record3", DESC = "Record 3"}, 
        new { ID = "Record4", DESC = "Record 4"}, 
       }; 
    EligibleList = new List<AssetClass> 
       { 
        new AssetClass { FEE_ID = "fid", ASSET_CLASS = "A" }, 
       }; 

我應該得到以下結果:

LookupList[0] == true 
    LookupList[1] == false 
    LookupList[2] == false 
    LookupList[3] == false 

有沒有更好的辦法來解決這個問題呢?

+2

*主列表*的擴展名是什麼意思? –

+1

爲什麼'LookupList'是一個匿名對象列表,而不僅僅是一個ID值列表。請記住,一旦你將一個匿名類型放入'List '中,你實際上已經放棄了它的所有有用方面;你幾乎肯定應該做其他的事情,比如使用一個命名類型(或者,在這種情況下,只是存儲字符串ID值)。 – Servy

回答

2
var results = LookupList.Select(l => EligibleList.Any(e => e.FEE_ID==l.ID)) 
         .ToList(); 
+1

這不會像現在那樣編譯他正在使用的集合。在循環內的List中進行線性搜索也是一個壞主意;幾乎在任何時候,你最好將你正在搜索的項目放到一個可以更有效搜索的集合中,比如'Dictionary'或'HashSet'。 – Servy

+0

現在,我們的目標就是讓它工作,然後將其優化。我實際上在IVisitor概念的正確軌道上,使用(動態)作爲類型特定方法實現的投射會調用正確的方法。 –

+0

對於原始問題,從長遠來看,查找列表的基本類型是什麼並不重要。我有一個班正在交2個名單。無論它們是字典還是哈希集,我對與之合作的集合的知識仍然非常有限。 –

0

以此爲定義SelectionCriteria<T>

public class SelectionCriteria<T> 
    where T : class 
{ 
    public IList<T> EligibleList { get; private set; } 
    public IList LookupList { get; private set; } 

    public SelectionCriteria(IList lookupList, IList<T> eligibleList) 
    { 
     LookupList = lookupList; 
     EligibleList = eligibleList; 
    } 

    public bool this[int index] 
    { 
     get 
     { 
      var element = LookupList[index]; 

      foreach (var item in EligibleList) 
      { 
       if (item.Equals(element)) 
       { 
        return true; 
       } 
      } 

      return false; 
     } 
    } 
} 

而且這是一個定義AssetClass

public class AssetClass : IEquatable<AssetClass> 
{ 
    public string FEE_ID { get; set; } 

    public string ASSET_CLASS { get; set; } 

    public bool Equals(AssetClass other) 
    { 
     return !ReferenceEquals(other, null) && other.FEE_ID == FEE_ID && other.ASSET_CLASS == ASSET_CLASS; 
    } 

    //Check to see if obj is a value-equal instance of AssetClass, if it's not, proceed 
    // to doing some reflection checks to determine value-equality 
    public override bool Equals(object obj) 
    { 
     return Equals(obj as AssetClass) || PerformReflectionEqualityCheck(obj); 
    } 

    //Here's where we inspect whatever other thing we're comparing against 
    private bool PerformReflectionEqualityCheck(object o) 
    { 
     //If the other thing is null, there's nothing more to do, it's not equal 
     if (ReferenceEquals(o, null)) 
     { 
      return false; 
     } 

     //Get the type of whatever we got passed 
     var oType = o.GetType(); 
     //Find the ID property on it 
     var oID = oType.GetProperty("ID"); 

     //Get the value of the property 
     var oIDValue = oID.GetValue(o, null); 

     //If the property type is string (so that it matches the type of FEE_ID on this class 
     // and the value of the strings are equal, then we're value-equal, otherwise, we're not 
     return oID.PropertyType == typeof (string) && FEE_ID == (string) oIDValue; 
    } 
} 

你可以得到在存在符合條件的項目列表中找到的元素在查找項目列表中,如下所示:

for (var i = 0; i < assetClassSelectionCriteria.LookupList.Count; ++i) 
{ 
    Console.WriteLine("LookupList[{0}] == {1}", i, assetClassSelectionCriteria[i]); 
} 

你也可以使用PerformReflectionEqualityCheck以下的AssetClass,如果你不喜歡「主列表的擴展名」看到反射善良

private bool PerformReflectionEqualityCheck(object o) 
{ 
    if (ReferenceEquals(o, null)) 
    { 
     return false; 
    } 

    dynamic d = o; 

    try 
    { 
     return FEE_ID == (string) d.ID; 
    } 
    catch 
    { 
     return false; 
    } 
} 

如果你的意思是一個擴展方法,然後,而不是聲明在SelectionCriteria<T>索引器得到的結果,你可以做這樣的事情:

public static class SelectionCriteriaExtensions 
{ 
    public static bool IsLookupItemEligible<T>(this SelectionCriteria<T> set, int index) 
     where T : class 
    { 
     var element = set.LookupList[index]; 

     foreach (var item in set.EligibleList) 
     { 
      if (item.Equals(element)) 
      { 
       return true; 
      } 
     } 

     return false; 
    } 
} 

,並調用它像這樣:

assetClassSelectionCriteria.IsLookupItemEligible(0); 
相關問題