1

这不是真正的问题标题,因为我真的不知道问题出在哪里,所以我只是猜测。

故事开始尝试向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成员的访问修饰符是publicSerializableDynamicObject

客户日志 =Stackoverflow

方案二:

类中dynamicProperties成员的访问修饰符是私有的或受保护的或其他。SerializableDynamicObject

客户日志 =null


问题 :

  • 为什么更改(dynamicProperties成员)访问修饰符时客户端输出不同?
  • 从内部方法(setValue,方法)访问成员是否getValue有限制(相同的类,相同的程序集,相同的命名空间)?
  • 我认为问题来自SerializableDynamicObjecttrue吗?还是由于覆盖SerializableDynamicMetaObject而来自类(BindSetMember,方法) ?BindGetMember

我不是那个专业的c#书呆子,所以如果问题太详细太长而无法讨论太琐碎的问题,请原谅我!

4

0 回答 0