Метод расширения .AsQueryable()
возвращает экземпляр EnumerableQuery<T>
wrapper class, если он вызван тем, что еще не было 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
}
Однако это, как правило, довольно неплохо. 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; }
}
}
Это будет и выступать в качестве обертки для IQueryable<T>
и обеспечения доступа словаря к первоначальному словаря , Но, с другой стороны, любой, кто пытается получить словарь, должен был знать, что такое параметры типового типа (например, <string, string>
, <int, string>
и т. Д.), Чтобы успешно выполнить его.
Подсказка с закрытым полем «Перечислимые».Я даже включил резерв в свой код ('if (pInfo == null), затем создайте новый словарь и добавьте KeyValuePairs вручную'), чтобы поддерживать совместимость с будущими версиями. –