152 lines
4.5 KiB
C#
152 lines
4.5 KiB
C#
// Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
|
|
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Dynamic;
|
|
using System.Web.WebPages.Resources;
|
|
|
|
namespace System.Web.WebPages
|
|
{
|
|
/// <summary>
|
|
/// This is a wrapper around PageDataDictionary[[dynamic]] which allows dynamic
|
|
/// access (e.g. dict.Foo). Like PageDataDictionary, it returns null if the key is not found,
|
|
/// instead of throwing an exception.
|
|
/// This class is intended to be used as DynamicPageDataDictionary[[dynamic]]
|
|
/// </summary>
|
|
// This is a generic type because C# does not allow implementing an interface
|
|
// involving dynamic types (implementing IDictionary<object, dynamic> causes
|
|
// a compile error
|
|
// http://blogs.msdn.com/cburrows/archive/2009/02/04/c-dynamic-part-vii.aspx).
|
|
internal class DynamicPageDataDictionary<TValue> : DynamicObject, IDictionary<object, TValue>
|
|
{
|
|
private PageDataDictionary<TValue> _data;
|
|
|
|
public DynamicPageDataDictionary(PageDataDictionary<TValue> dictionary)
|
|
{
|
|
_data = dictionary;
|
|
}
|
|
|
|
public ICollection<object> Keys
|
|
{
|
|
get { return _data.Keys; }
|
|
}
|
|
|
|
public ICollection<TValue> Values
|
|
{
|
|
get { return _data.Values; }
|
|
}
|
|
|
|
public int Count
|
|
{
|
|
get { return _data.Count; }
|
|
}
|
|
|
|
public bool IsReadOnly
|
|
{
|
|
get { return _data.IsReadOnly; }
|
|
}
|
|
|
|
public TValue this[object key]
|
|
{
|
|
get { return _data[key]; }
|
|
set { _data[key] = value; }
|
|
}
|
|
|
|
public override bool TryGetMember(GetMemberBinder binder, out object result)
|
|
{
|
|
result = _data[binder.Name];
|
|
// We return true here because PageDataDictionary returns null if the key is not
|
|
// in the dictionary, so we simply pass on the returned value.
|
|
return true;
|
|
}
|
|
|
|
public override bool TrySetMember(SetMemberBinder binder, object value)
|
|
{
|
|
// This cast should always succeed assuming TValue is dynamic.
|
|
TValue v = (TValue)value;
|
|
_data[binder.Name] = v;
|
|
return true;
|
|
}
|
|
|
|
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
|
|
{
|
|
if (indexes == null || indexes.Length != 1)
|
|
{
|
|
throw new ArgumentException(WebPageResources.DynamicDictionary_InvalidNumberOfIndexes);
|
|
}
|
|
|
|
result = _data[indexes[0]];
|
|
// We return true here because PageDataDictionary returns null if the key is not
|
|
// in the dictionary, so we simply pass on the returned value.
|
|
return true;
|
|
}
|
|
|
|
public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
|
|
{
|
|
if (indexes == null || indexes.Length != 1)
|
|
{
|
|
throw new ArgumentException(WebPageResources.DynamicDictionary_InvalidNumberOfIndexes);
|
|
}
|
|
|
|
// This cast should always succeed assuming TValue is dynamic.
|
|
_data[indexes[0]] = (TValue)value;
|
|
return true;
|
|
}
|
|
|
|
public void Add(object key, TValue value)
|
|
{
|
|
_data.Add(key, value);
|
|
}
|
|
|
|
public bool ContainsKey(object key)
|
|
{
|
|
return _data.ContainsKey(key);
|
|
}
|
|
|
|
public bool Remove(object key)
|
|
{
|
|
return _data.Remove(key);
|
|
}
|
|
|
|
public bool TryGetValue(object key, out TValue value)
|
|
{
|
|
return _data.TryGetValue(key, out value);
|
|
}
|
|
|
|
public void Add(KeyValuePair<object, TValue> item)
|
|
{
|
|
_data.Add(item);
|
|
}
|
|
|
|
public void Clear()
|
|
{
|
|
_data.Clear();
|
|
}
|
|
|
|
public bool Contains(KeyValuePair<object, TValue> item)
|
|
{
|
|
return _data.Contains(item);
|
|
}
|
|
|
|
public void CopyTo(KeyValuePair<object, TValue>[] array, int arrayIndex)
|
|
{
|
|
_data.CopyTo(array, arrayIndex);
|
|
}
|
|
|
|
public bool Remove(KeyValuePair<object, TValue> item)
|
|
{
|
|
return _data.Remove(item.Key);
|
|
}
|
|
|
|
public IEnumerator<KeyValuePair<object, TValue>> GetEnumerator()
|
|
{
|
|
return _data.GetEnumerator();
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return _data.GetEnumerator();
|
|
}
|
|
}
|
|
}
|