这不是真正的问题标题,因为我真的不知道问题出在哪里,所以我只是猜测。
故事开始尝试向dynamic
我的 WCF 服务发送和接收类型,这导致我使用DLR 动态类型的 WCF 序列化!
SerializableDynamicObject类
public class SerializableDynamicObject : IDynamicMetaObjectProvider
{
private IDictionary<string,object> dynamicProperties = new Dictionary<string,object>();
#region IDynamicMetaObjectProvider implementation
public DynamicMetaObject GetMetaObject (Expression expression)
{
return new SerializableDynamicMetaObject(expression,
BindingRestrictions.GetInstanceRestriction(expression, this), this);
}
#endregion
#region Helper methods for dynamic meta object support
internal object setValue(string name, object value)
{
dynamicProperties.Add(name, value);
return value;
}
internal object getValue(string name)
{
object value;
if(!dynamicProperties.TryGetValue(name, out value)) {
value = null;
}
return value;
}
internal IEnumerable<string> getDynamicMemberNames()
{
return dynamicProperties.Keys;
}
#endregion
}
SerializableDynamicMetaObject类
public class SerializableDynamicMetaObject : DynamicMetaObject
{
Type objType;
public SerializableDynamicMetaObject(Expression expression, BindingRestrictions restrictions, object value)
: base(expression, restrictions, value)
{
objType = value.GetType();
}
public override DynamicMetaObject BindGetMember (GetMemberBinder binder)
{
var self = this.Expression;
var dynObj = (SerializableDynamicObject)this.Value;
var keyExpr = Expression.Constant(binder.Name);
var getMethod = objType.GetMethod("getValue", BindingFlags.NonPublic | BindingFlags.Instance);
var target = Expression.Call(Expression.Convert(self, objType),
getMethod,
keyExpr);
return new DynamicMetaObject(target,
BindingRestrictions.GetTypeRestriction(self, objType));
}
public override DynamicMetaObject BindSetMember (SetMemberBinder binder, DynamicMetaObject value)
{
var self = this.Expression;
var keyExpr = Expression.Constant(binder.Name);
var valueExpr = Expression.Convert(value.Expression, typeof(object));
var setMethod = objType.GetMethod("setValue", BindingFlags.NonPublic | BindingFlags.Instance);
var target = Expression.Call(Expression.Convert(self, objType),
setMethod,
keyExpr,
valueExpr);
return new DynamicMetaObject(target,
BindingRestrictions.GetTypeRestriction(self, objType));
}
public override IEnumerable<string> GetDynamicMemberNames ()
{
var dynObj = (SerializableDynamicObject)this.Value;
return dynObj.getDynamicMemberNames();
}
}
使用这个习惯SerializableDynamicObject
并解决了很多问题后,我终于停止了一个非常奇怪的行为(至少对我来说)。
@服务 伪代码:
dynamic X = new SerializableDynamicObject();
X . Ask = "Stackoverflow";
Ping ( X ); // Send to Client
@客户端 伪代码:
// Receiving X SerializableDynamicObject
dynamic Y = X;
Log ( Y . Ask ); // Logging @ Chrome Javascript Console (Silverlight Client)
这花了 2 天时间才最终幸运地到达它:(
方案一:
类中dynamicProperties
成员的访问修饰符是public。SerializableDynamicObject
客户日志 =Stackoverflow
方案二:
类中dynamicProperties
成员的访问修饰符是私有的或受保护的或其他。SerializableDynamicObject
客户日志 =null
问题 :
- 为什么更改(
dynamicProperties
成员)访问修饰符时客户端输出不同? - 从内部方法(
setValue
,方法)访问成员是否getValue
有限制(相同的类,相同的程序集,相同的命名空间)? - 我认为问题来自
SerializableDynamicObject
类true吗?还是由于覆盖SerializableDynamicMetaObject
而来自类(BindSetMember
,方法) ?BindGetMember
我不是那个专业的c#书呆子,所以如果问题太详细太长而无法讨论太琐碎的问题,请原谅我!