Jür*_*ock 7 .net c# dictionary iqueryable
我有一个通用字典传递给一个只接受IQueryable参数的方法
是否可以将可查询转换回原始字典?我并不是说要创建一个新词典.ToDictionary(...)
private static void Main()
{
var dict = new Dictionary<int, int>();
dict.Add(1,1);
SomeMethod(dict.AsQueryable());
}
public static void SomeMethod(IQueryable dataSource)
{
// dataSource as Dictionary<int, int> --> null
var dict = dataSource.???
}
Run Code Online (Sandbox Code Playgroud)
我知道在这个简单的例子中,这没有多大意义.但是在大图中我有一个接口,它要求我返回IQueryable一个dataSource.在实现上返回一个字典.在我的代码中的另一个地方,我有处理dataSources的类.
处理器知道dataSource将是一个Dictionary,但是如果我已经有一个Dictionary,我不想要创建另一个Dictionary的开销.
该.AsQueryable()扩展方法返回的实例,EnumerableQuery<T>包装类,如果它被称为的东西,是不是已经是一个IQueryable<T>.
此包装类具有一个.Enumerable具有internal访问权限的属性,该属性提供对.AsQueryable()调用的原始对象的访问.所以你可以这样做来取回原来的字典:
var dict = new Dictionary<int, int>();
dict.Add(1,1);
var q = dict.AsQueryable();
Type tInfo = q.GetType();
PropertyInfo pInfo = tInfo.GetProperties(BindingFlags.NonPublic |
BindingFlags.Instance)
.FirstOrDefault(p => p.Name == "Enumerable");
if (pInfo != null)
{
object originalDictionary = pInfo.GetValue(q, null);
Console.WriteLine(dict == originalDictionary); // true
}
Run Code Online (Sandbox Code Playgroud)
但是,这通常是一个非常糟糕的主意.internal由于某种原因,成员的访问权限受到限制,我认为没有任何保证内部实施.AsQueryable()在将来的某个时候不会发生变化.因此,最好的办法是找到一种方法使原始字典可访问,或者继续创建一个新字典.
private class DictionaryQueryHolder<TKey, TValue> : IQueryable<KeyValuePair<TKey, TValue>>
{
public IDictionary<TKey, TValue> Dictionary { get; private set; }
private IQueryable<KeyValuePair<TKey, TValue>> Queryable { get; set; }
internal DictionaryQueryHolder(IDictionary<TKey, TValue> dictionary)
{
Dictionary = dictionary;
Queryable = dictionary.AsQueryable();
}
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
{
return Queryable.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
public Expression Expression
{
get { return Queryable.Expression; }
}
public Type ElementType
{
get { return Queryable.ElementType; }
}
public IQueryProvider Provider
{
get { return Queryable.Provider; }
}
}
Run Code Online (Sandbox Code Playgroud)
这既可以作为字典的包装,IQueryable<T>也可以提供对原始字典的访问.但在另一方面,任何人试图检索字典必须知道什么泛型类型参数为(例如<string, string>,<int, string>等),以便顺利投放.
| 归档时间: |
|
| 查看次数: |
709 次 |
| 最近记录: |