深入理解 c# 第十四章 最终目标:动态地调用方法直到你弄到正确的名字

    class RumpelstiltskinTest
    {
        static void Main()//最终方法:动态地调用方法:直到你弄对正确的名字 
		//实现IDynamicMetaObjectProvider
        {
            Console.WriteLine("Testing first implementation");
            dynamic x = new Rumpelstiltskin("Hermione");
			//x {Chapter14.Rumpelstiltskin}
            x.Harry();
            x.Ron();
            x.Hermione();

            Console.WriteLine("Testing alternative implementation");
            // Now check the alternative implementation
            x = new Rumpelstiltskin("Ron");
            x.Harry();
            x.Ron();
            x.Hermione();
        }
    }
	
    public sealed class Rumpelstiltskin : IDynamicMetaObjectProvider
    {
        private readonly string name;
        public Rumpelstiltskin(string name)
        {
            this.name = name;
			//name "Hermione"
			//"Ron"
        }

        public DynamicMetaObject GetMetaObject(Expression expression)
		//expression {$arg0}
        {
            return new MetaRumpelstiltskin(expression, this);
        }

        private object RespondToWrongGuess(string guess)
		//guess "Harry"
        {
            Console.WriteLine("No, I'm not {0}! (I'm {1}.)",
                guess, name);
            return false;
        }

        private object RespondToRightGuess()
        {
            Console.WriteLine("Curses! Foiled again!");
            return true;
        }

        private class MetaRumpelstiltskin : DynamicMetaObject
        {
            private static readonly MethodInfo RightGuessMethod =
                typeof(Rumpelstiltskin).GetMethod("RespondToRightGuess",
                BindingFlags.Instance | BindingFlags.NonPublic);

            private static readonly MethodInfo WrongGuessMethod =
                typeof(Rumpelstiltskin).GetMethod("RespondToWrongGuess",
                BindingFlags.Instance | BindingFlags.NonPublic);

            internal MetaRumpelstiltskin
                (Expression expression, Rumpelstiltskin creator)
				//creator {Chapter14.Rumpelstiltskin}
                : base(expression, BindingRestrictions.Empty, creator)
            {}

            public override DynamicMetaObject BindInvokeMember
                (InvokeMemberBinder binder, DynamicMetaObject[] args)
            {
                Rumpelstiltskin targetObject = (Rumpelstiltskin)base.Value;
				//targetObject {Chapter14.Rumpelstiltskin}
                Expression self = Expression.Convert(base.Expression,
                    typeof(Rumpelstiltskin));
					//self {Convert($arg0)}

                Expression targetBehavior;
                if (binder.Name == targetObject.name)
                {
                    targetBehavior = Expression.Call(self, RightGuessMethod);
					//targetBehavior {Convert($arg0).RespondToWrongGuess("Harry")}
					//{Convert($arg0).RespondToWrongGuess("Ron")}
                }
                else
                {
                    targetBehavior = Expression.Call(self, WrongGuessMethod,
                        Expression.Constant(binder.Name));
                }

                var restrictions = BindingRestrictions.GetInstanceRestriction
                    (self, targetObject);
					//restrictions "{var Param_0; ... }"
                return new DynamicMetaObject(targetBehavior, restrictions);
            }
        }
    }	

  其实也没搞懂,复杂

  实现IDynamicMetaObjectProvider的难点并不是接口本身,而是构建该接口的唯一方法
所返回的DynamicMetaObject。 DynamicMetaObject有点像DynamicObject,它包含
很多方法,可以覆盖它们,并影响相应的行为。我们覆盖DynamicMetaObject.BindGetMember。
在被覆盖的方法内,它不会直接处理所需的行为,而会构建一个表达式树来描述行为以及
行为产生的环境。这种额外的间接层就是它称为元对象的原因。
  Rumpelstiltskin类型。给定的名称(存储在一个非常常见的字符串变量里)来创建
Rumpelstiltskin的实例,然后在该对象上调用方法,直到调用方法的名称与字符串相同。
  
输出
Testing first implementation
No, I'm not Harry! (I'm Hermione.)
No, I'm not Ron! (I'm Hermione.)
Curses! Foiled again!
Testing alternative implementation
No, I'm not Harry! (I'm Ron.)
Curses! Foiled again!
No, I'm not Hermione! (I'm Ron.)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值