2015-11-26 10 views
0

我有一個對象列表。 我有一個與列表類型相同的單個項目。我可以根據對象的屬性使用強類型參數

我想創建一個通用的擴展方法(稱爲查找)基於單個obj以及其強類型屬性的任意列表來查找列表中的項目。

這裏是我想調用的方法:

var obj = new SomeObject() { ... } ; 
var list = new List<SomeObject>() { ... }; 

// Find similar objects 
list.Find(obj, x => x.Id,y => y.Description); 

是這種安排可能嗎?

FirstOrDefault將在下面的註釋中工作。但是,我正在尋找一種在不同情況下使用模式的方法,這可能不是一種簡單的查找方式。

+0

使用FirstOrDefault –

+0

已經存在所謂的'Find'的擴展方法,並作爲建議, 'FirstOrDefault'也可以輕鬆完成同樣的工作。如果您需要查找列表中符合條件的所有元素,請使用「Where」擴展方法 –

+0

您是否試圖根據匹配的屬性值查找單個結果或多個結果? –

回答

1

在我看來,您似乎並沒有像使用正常的Where子句那樣節省大量的時間/精力,而是對您之後的任何屬性進行過濾。

var findResults = list.Where(x => x.Id == obj.Id || x.Description == obj.Description); 
2

你可以做到這一點

public static T Find<T>(this IEnumerable<T> source, params Func<T,bool>[] condition) 
{ 
    return source.FirstOrDefault(o => condition.All(f => f(o))); // use All for && or use Any for || 
} 

,並使用它

var item = list.Find(x=> x.Id == obj.Id,x=> x.Description == obj.Description); 

可以使用對象,如果你想通過鑄造性能反對,使這項工作更普遍。但是這樣會稍微慢一些,並且您必須注意,爲了使其正常工作,必須重寫方法自定義類型

public static T Find<T>(this IEnumerable<T> source, T obj, params Func<T, object>[] condition) 
{ 
    return source.FirstOrDefault(o => condition.All(f => f(o).Equals(f(obj)))); 
} 

然後你可以這樣稱呼它。

var item = list.Find(obj, x => x.Id,y => y.Description); 

如果您想返回所有類似的項目,則可以使用Where。只需更改FirstOrDefaultWhere和返回類型的方法爲IEnumerable<T>

+0

我理解你的邏輯,但我在比較方面想的是通用的,所以我可以傳遞參數。如果C#可以推斷變量,那將是非常酷的。也許微軟可以提供一個params 的概念。然後你可以調用像public static DoSomething(o.Id,o.Description)這樣的方法。 – jwize

+0

@jwize你可以使用'dynamic'類型,它的實際類型在運行時被評估。但由於類型不是恆定的,因此速度會更慢。 –

0

也許你應該考慮繼續這樣的:

var myResult = from currentObject in mylist 
       where currentObject == mySingleObject // change it by your matching criterias linked by && or || (as in if ...) 
       // NB: you can also override the == operator in your object definition 
       // but as mentionned below, it won't work for generic types 
       select currentObject; 
+0

運算符重載在Find 中不適用,其中T未知。 – jwize

+0

你是對的:我編輯了答案 –

相關問題