いいえ、残念ながらこれは不可能です。特定のデータ ソースが与えられた場合、そのような検索はかなり単純になる可能性がありますが、より一般的な方法 (のようにBindingSource
) で検索を行うと、透過性が少し低下します。1 つは、構文がわかりにくいことです。これはやや不自然な解決策です:
public class Key
{
public string PropertyName {get; set;}
public object Value {get; set;}
}
public static int Find(this BindingSource source, params Key[] keys)
{
PropertyDescriptor[] properties = new PropertyDescriptor[keys.Length];
ITypedList typedList = source as ITypedList;
if(source.Count <= 0) return -1;
PropertyDescriptorCollection props;
if(typedList != null) // obtain the PropertyDescriptors from the list
{
props = typedList.GetItemProperties(null);
}
else // use the TypeDescriptor on the first element of the list
{
props = TypeDescriptor.GetProperties(source[0]);
}
for(int i = 0; i < keys.Length; i++)
{
properties[i] = props.Find(keys[i].PropertyName, true, true); // will throw if the property isn't found
}
for(int i = 0; i < source.Count; i++)
{
object row = source[i];
bool match = true;
for(int p = 0; p < keys.Count; p++)
{
if(properties[p].GetValue(row) != keys[p].Value))
{
match = false;
break;
}
}
if(match) return i;
}
return -1;
}
次のように呼び出すことができます。
BindingSource source = // your BindingSource, obviously
int index = source.Find(
new Key { PropertyName = "PetType", Value = "Dog" },
new Key { PropertyName = "Gender", Value = "M" });
これを使用できるようにするには、よりスマートな比較アルゴリズムが必要ですが、それは読者の課題として残します。の実装を確認IComparable
することは良い出発点です。それにもかかわらず、その概念は、実装の特定のポイントに関係なく継続する必要があります。
これは、基になるデータ ソースによって実装される可能性のあるパフォーマンスの最適化を利用しないことに注意してくださいFind
。