没有为有限可见性类型调用DynamicObject的TryConvert

时间:2013-11-07 08:51:59

标签: c# microsoft-dynamics dynamicobject

我想知道为什么将DynamicObject派生类的可见性更改为private会阻止框架调用TryConvert。

即。以下代码输出如下:

Calling TryGetMember
Calling TryConvert

但如果我改变

public sealed class DynamicJsonObject

到私有(它嵌套在DynamicJsonConverter中),然后它是

Calling TryGetMember
InvalidCastException is thrown

(无法将'DynamicJsonObject'类型的对象强制转换为'System.Collections.Generic.IDictionary`2 [System.String,System.Object]

在System.Dynamic.UpdateDelegates.UpdateAndExecute1 [T0,TRet]的CallSite.Target(Closure,CallSite,Object)中(CallSite站点,T0 arg0))

代码:

void Main()
{
   var serializer = new JavaScriptSerializer();
   serializer.RegisterConverters(new[] { new DynamicJsonConverter() });

   dynamic result = serializer.Deserialize("{ 'response' : { 'data' : '1', 's' : -1 } }", typeof(object));
   ((IDictionary<string, object>)result.response).Dump();
}

public sealed class DynamicJsonConverter : JavaScriptConverter
{
    public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
    {
        if (dictionary == null)
            throw new ArgumentNullException("dictionary");

        return type == typeof(object) ? new DynamicJsonObject(dictionary) : null;
    }

    public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override IEnumerable<Type> SupportedTypes
    {
        get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { typeof(object) })); }
    }

    public sealed class DynamicJsonObject : DynamicObject
    {
        private readonly IDictionary<string, object> _dictionary;       

        public DynamicJsonObject(IDictionary<string, object> dictionary)
        {
            if (dictionary == null)
                throw new ArgumentNullException("dictionary");
            _dictionary = dictionary;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            Console.WriteLine("Calling TryGetMember");
            if (!_dictionary.TryGetValue(binder.Name, out result))
            {
                result = null;
                return true;
            }
            var dictionary = result as IDictionary<string, object>;
            if (dictionary != null)
            {
                result = new DynamicJsonObject(dictionary);
                return true;
            }
            var arrayList = result as ArrayList;
            if (arrayList != null && arrayList.Count > 0)
            {
                if (arrayList[0] is IDictionary<string, object>)
                    result = new List<object>(arrayList.Cast<IDictionary<string, object>>().Select(x => new DynamicJsonObject(x)));
                else
                    result = new List<object>(arrayList.Cast<object>());
            }
            return true;
        }

        public override bool TryConvert(ConvertBinder binder, out object result)
        {
            Console.WriteLine("Calling TryConvert");
            result = null;
            if (binder.Type == typeof(IDictionary<string, object>))
            {
                result = _dictionary;
                return true;
            }           
            return base.TryConvert(binder, out result);
        }       
    }
}

0 个答案:

没有答案