どこに問題があるのか 本当にわからないので、これは本当の質問のタイトルではありません.
ストーリーは、WCF サービスとの間で型を送受信しようとし始め、DLR 動的型の WCF シリアル化にdynamic
つながりました!
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日かかりました:(
シナリオ I :
クラスのdynamicProperties
メンバーのアクセス修飾子はpublicです。SerializableDynamicObject
クライアント ログ =Stackoverflow
シナリオ II :
クラス内のdynamicProperties
メンバーのアクセス修飾子は、プライベートまたは保護されています。SerializableDynamicObject
クライアント ログ =null
質問 :
dynamicProperties
(メンバー) アクセス修飾子を変更すると、クライアントの出力が異なるのはなぜですか?setValue
内部メソッド ( 、メソッド)からのメンバーへのアクセスには制限がありますかgetValue
(同じクラス、同じアセンブリ、同じ名前空間)?- 問題は
SerializableDynamicObject
クラスtrueから来ると思いましたか? またはオーバーライドSerializableDynamicMetaObject
のためにクラス(BindSetMember
、BindGetMember
メソッド)からのものですか?
私はプロの c# オタクではないので、議論するにはあまりにも些細な問題を言及するにはあまりにも詳細な長い質問だった場合は、ご容赦ください。