Jo Shields a575963da9 Imported Upstream version 3.6.0
Former-commit-id: da6be194a6b1221998fc28233f2503bd61dd9d14
2014-08-13 10:39:27 +01:00

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();
}
}
}