我想知道为什么将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);
}
}
}