有没有办法要求.ToLookupLINQ提供的功能有多个键?
我承认起初这似乎不直观,我期待没有实际的方法来做到这一点,但我希望有人知道一种方式.
我基本上希望能够通过两个值进行查找,例如a string和an int,并使用这两个值检索对象.
public class MyClass {
public string StringProp {get;set;}
public int IntProp {get;set;}
public object MoreData {get;set;}
}
public class Main {
public void Main() {
HashSet<MyClass> set = new HashSet<MyClass>();
set.Add(new MyClass {StringProp = "a", IntProp = 1, MoreData = null});
set.Add(new MyClass {StringProp = "c", IntProp = 4, MoreData = new object()});
set.Add(new MyClass {StringProp = "a", IntProp = 2, MoreData = "upupdowndown"});
set.Add(new MyClass {StringProp = "c", IntProp = 1, MoreData = string.Empty});
set.Add(new MyClass {StringProp = "c", IntProp = 4, MoreData = string.Empty});
// Using 'var' because I don't know how this would be defined.
// I recognize that this will not compile - but this is what I'm trying to do.
var lookup = set.ToLookup(x => x.StringProp && x.IntProp)
MyClass c = lookup["a", 1].First(); // Should return the first element
IEnumerable<MyClass> list = lookup["c", 4]; // Should return the 2nd and last elements
}
}
Run Code Online (Sandbox Code Playgroud)
Gab*_*abe 22
我会用Tuples来做这种事情:
var lookup = set.ToLookup(x => Tuple.Create(x.StringProp, x.IntProp));
MyClass c = lookup[Tuple.Create("a", 1)].First();
IEnumerable<MyClass> list = lookup[Tuple.Create("c", 4)];
Run Code Online (Sandbox Code Playgroud)
所以其他答案都是我想的,但每次想要从查找中获取值时创建元组或匿名类有点麻烦.如果您只是将字符串和int粘贴到索引器中以获取值,那不是很好吗?通过创建自己的类来使用索引器包装查找,您可以完全执行此操作.
public class MyLookup<T1, T2, TOut>
{
private ILookup<Tuple<T1, T2>, TOut> lookup;
public MyLookup(IEnumerable<TOut> source, Func<TOut, Tuple<T1, T2>> keySelector)
{
lookup = source.ToLookup(keySelector);
}
public IEnumerable<TOut> this[T1 first, T2 second]
{
get
{
return lookup[Tuple.Create(first, second)];
}
}
//feel free to either expose the lookup directly, or add other methods to access the lookup
}
Run Code Online (Sandbox Code Playgroud)
以下是使用它的示例:
IEnumerable<MyClass> data = null; //TODO populate with real data
var lookup = new MyLookup<string, int, MyClass>(data
, item => Tuple.Create(item.StringProp, item.IntProp));
IEnumerable<MyClass> someValue = lookup["c", 4];
Run Code Online (Sandbox Code Playgroud)
虽然不是您真正想要的,但是可以很好地完成工作:
var r = set.ToLookup(x => new { x.StringProp, x.IntProp });
var f = r[ new { StringProp = "a", IntProp = 1 } ].First();
Run Code Online (Sandbox Code Playgroud)