21 C# 第十七章(三) 使用动态对象

使用动态对象

使用动态对象进行编程,开发人员可以用一个动态调度机制对设想的操作进行编码。"运行时" 会在程序执行时对这个机制进行解析,而不是由编译器在编译时验证和绑定。


一个简单的实例 来自MSDN  

using System;

namespace DynamicExamples
{
    class Program
    {
        static void Main(string[] args)
        {
            ExampleClass ec = new ExampleClass();
            Console.WriteLine(ec.exampleMethod(10));
            Console.WriteLine(ec.exampleMethod("value"));

            //**************************  Point 1  **************************
            // The following line causes a compiler error because exampleMethod
            // takes only one argument.
            //Console.WriteLine(ec.exampleMethod(10, 4));
            //***************************************************************


            dynamic dynamic_ec = new ExampleClass();
            Console.WriteLine(dynamic_ec.exampleMethod(10));

            //**************************  Point 2  **************************
            // Because dynamic_ec is dynamic, the following call to exampleMethod
            // with two arguments does not produce an error at compile time.
            // However, itdoes cause a run-time error. 
            //Console.WriteLine(dynamic_ec.exampleMethod(10, 4));
            //***************************************************************

            Console.ReadKey();
        }
    }

    class ExampleClass
    {
        //static dynamic field;
        dynamic prop { get; set; }

        public dynamic exampleMethod(dynamic d)
        {
            dynamic local = "Local variable";
            int two = 2;

            if (d is int)
            {
                return local;
            }
            else
            {
                return two;
            }
        }
    }
}


注意注释的重点的两行,虽然被注释了但意义重大。

在point 1使用的是 基础类型,如果发现被调用的类的成员不存在 编译时就会 报错
在point 2使用的是 dynamic类型,如果发现被调用的类的成员不存在会在 运行时抛出 异常


如果一变量声明为dynamic,编译时不会检查指定的成员是否存在,甚至不会检查dynamic的基础类型是什么。
但dynamic类型在运行时发现调用的成员不存在,则会引发 Microsoft.CSharp.RuntimeBinder.RuntimeBinderException。


使用dynamic的好处

这里有一个解析XML文件的小例子,它包含了两部分,自定义的一个dynamic类型和使用它,尤其在使用它的时候,他比正常的解析XML文件的代码要简洁。


DynamicXml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Dynamic;
using System.Xml.Linq;


namespace dyanmic_parse_xml
{
    public class DynamicXml : DynamicObject 
    {
        private XElement Element{get; set;}

        public DynamicXml(XElement element)
        {
            Element = element;
        }

        public static DynamicXml Parse(string str)
        {
            return new DynamicXml(XElement.Parse(str));
        }


        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            bool success = false;
            result = null;

            XElement firstDescendant = Element.Descendants(binder.Name).FirstOrDefault();

            if (firstDescendant != null)
            {
                if (firstDescendant.Descendants().Count() > 0)
                {
                    result = new DynamicXml(firstDescendant);
                }
                else
                {
                    result = firstDescendant.Value;
                }
                success = true;
            }

            return success;
        }

        public override bool  TrySetMember(SetMemberBinder binder, object value)
        {
            bool success = false;

            XElement firstDescendant = Element.Descendants(binder.Name).FirstOrDefault();

            if (firstDescendant != null)
            {
                if (value.GetType() == typeof(XElement))
                {
                    firstDescendant.ReplaceWith(value);
                }
                else
                {
                    firstDescendant.Value = value.ToString();
                }

                success = true;
            }
            return success;
        }
    }
}

Program.cs

using System;
using System.Linq;
using System.Xml.Linq;

namespace dyanmic_parse_xml
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Use legacy way");
            Console.WriteLine("=========================================================");
            XElement person = XElement.Parse(@"<Person>
                                               <FirstName>Inigo</FirstName>
                                               <LastName>Montoya</LastName>
                                               </Person>");

            Console.WriteLine("{0} {1}", person.Descendants("FirstName").FirstOrDefault().Value,
                                         person.Descendants("LastName").FirstOrDefault().Value);


            Console.WriteLine("\nUse dynamic way");
            Console.WriteLine("=====================================&#
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值