动态对象DynamicObject实现让字典书写更优美

我想用过MVC的人都知道一件事,viewbag的值是存储在viewdata里面的。

先看以下组图:

看了上图是不是感觉很神奇,Dictionary<string, object>也可以这样使用~

实现主要继承了DynamicObject

接下来直接贴代码:

/// <summary>
    /// 动态对象
    /// </summary>
    public class VarObject : DynamicObject
    {
        /// <summary>
        /// 数据字段
        /// </summary>
        private Dictionary<string, object> ViewData = new Dictionary<string, object>();

        /// <summary>
        /// 调用 varo(); 时执行
        /// dynamic varo = new VarObject();
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="args"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool TryInvoke(InvokeBinder binder, object[] args, out object result)
        {
            return base.TryInvoke(binder, args, out result);
        }

        /// <summary>
        /// 调用 varo.Method(); 时执行
        /// dynamic varo = new VarObject();
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="args"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
        {
            return base.TryInvokeMember(binder, args, out result);
        }

        /// <summary>
        /// 调用 varo + varo; 时执行
        /// dynamic varo = new VarObject();
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="arg"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result)
        {
            return base.TryBinaryOperation(binder, arg, out result);
        }

        /// <summary>
        /// 调用 varo++; 时执行
        /// dynamic varo = new VarObject();
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool TryUnaryOperation(UnaryOperationBinder binder, out object result)
        {
            return base.TryUnaryOperation(binder, out result);
        }

        /// <summary>
        /// 调用 varo["key"]; 时执行
        /// dynamic varo = new VarObject();
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="indexes"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
        {
            if (indexes == null || indexes.Length != 1)
            {
                throw new ArgumentException("indexes");
            }

            result = null;
            string key = indexes[0] as string;
            if (key != null)
            {
                result = ViewData[key];
            }
            else
            {
                throw new ArgumentException("indexes");
            }
            return true;
        }

        /// <summary>
        /// 调用 varo["key"] = "value"; 时执行
        /// dynamic varo = new VarObject();
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="indexes"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value)
        {
            if (indexes == null || indexes.Length != 1)
            {
                throw new ArgumentException("indexes");
            }

            string key = indexes[0] as string;
            if (key != null)
            {
                ViewData[key] = value;
                return true;
            }
            else
            {
                throw new ArgumentException("indexes");
            }
        }

        /// <summary>
        /// 获取所有key
        /// </summary>
        /// <returns></returns>
        public override IEnumerable<string> GetDynamicMemberNames()
        {
            return ViewData.Keys;
        }

        /// <summary>
        /// 调用 varo.key; 时执行
        /// dynamic varo = new VarObject();
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            result = ViewData[binder.Name];
            return true;
        }

        /// <summary>
        /// 调用 varo.key = "value"; 时执行
        /// dynamic varo = new VarObject();
        /// </summary>
        /// <param name="binder"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            ViewData[binder.Name] = value;
            return true;
        }
    }

运行代码:

    class Program
    {

        static void Main(string[] args)
        {
            dynamic varo = new VarObject();

            varo.a = "value";

            varo.b = "2";

            varo["c"] = 3;

            var d = varo++;

            var e = varo + varo;

            varo(); 

            varo.Method(); 

            foreach(var v in varo.GetDynamicMemberNames())
            {
                Console.WriteLine(v);
            }

            Console.WriteLine("done.");
            Console.ReadKey();
        }
    }
时间: 2024-10-04 13:39:43

动态对象DynamicObject实现让字典书写更优美的相关文章

自定义动态对象

1,自定义动态对象需要继承DynamicObject类 2,可根据需要,重写不同的DynamicObject方法 -----------------------------------------------------DynamicClass.cs  using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using S

Unity动态对象优化

对于静态对象,Unity可以使用通过勾选Static,然后让Unity自身进行优化Draw Calls,但是对于动态对象,Unity在这方面没有处理,这就需要我们自己去实现,实现的原理就是首先去遍历每个对象的SkinnderMeshRenderer,然后将其所有的动态对象组合成一个大的对象并且将骨骼动画赋值给他,这样,我们就实现了动态对象的优化,代码如下: public static void CombineToMesh(GameObject _go)     {         Skinned

动态对象创建(二)重载new和delete

前言 上文我简单介绍了一下动态对象创建的方法,这一篇文章的内容主要是对重载new和delete做一些讲解,也希望能够得到博友们的指点,在这里谢过大家. 通常我们为了一些目的而使用new和delete的内存分配系统,但是在特殊情况下,它并不能够满足需要.最常见的改变分配系统的原因是出于效率考虑:也许要创建和销毁一个特定的类的非常多的对象以至于这个运算变成了速度的瓶颈.C++允许重载new和delete来实现我们自己的存储分配方案,所以可以用它来处理问题. 另一个问题就是堆碎片:分配不同大小的内存可

设计一个不强引用对象的单例字典

大家都知道,使用NSDictionary存储对象的时候会强引用对象,导致被存储对象的引用计数+1,有时候,我们想用单例来存储对象,但又不希望强引用存储的对象,这该怎么实现呢? 在这里,我们可以使用NSMapTable来实现这个功能. 我直接给出源码: WeakDictionary.h   +   WeakDictionary.m // // WeakDictionary.h // 弱引用字典 // // http://www.cnblogs.com/YouXianMing/ // Copyrig

Objective-C 奇巧淫技--让对象伪装成一个字典

奇技淫巧 指过于奇巧而无益的技艺与制品. 转载请注明出处 uxyheaven csdn博客 其实这个技巧特定情况下,要求不高还挺是有用的. 我们原本有个接口1,设计的-.,为了灵活性嘛,就用了字典 - (void)method1:(NSDictionary *)dic { NSString *name = dic[@"name"]; NSLog(@"%s, name: %@",__FUNCTION__, name); } 等到我们水平提高了,发现代码应该这么写 @p

Asp.net动态页面静态化之字典哈希表的输出已及遍历判断的实现

Asp.net动态页面静态化之字典哈希表的输出已经遍历判断的实现 using System; using System.Collections.Generic; using System.Linq; using System.Web; using NVelocity.Runtime; using NVelocity; using NVelocity.App; using System.Collections; namespace czbk { /// <summary> /// diction

Markdown:让书写更美好

# Markdown:让书写更美好 ![text](http://wenchao-img.qiniudn.com/a53403c34c199fdd759571c2997ed910.png) ## Markdown简介 > Markdown 是一种轻量级标记语言,创始人为约翰·格鲁伯(John Gruber).它允许人们"使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档".[1]这种语言吸收了很多在电子邮件中已有的纯文本标记的特性. > --维

动态对象创建

C++的动态对象创建 对象创建 当创建一个C++对象时,会发生两件事: (1)为对象分配内存 (2)调用构造函数来初始化那个内存 然而,为对象分配内存可以用以下几种方式或在可选择的时间发生: (1)在静态存储区域,存储空间在程序开始之前就可以分配.这个存储空间在整个运行期间都存在. (2)无论何时到达一个特殊的执行点(左大括号)时,存储单元都可以在栈上被创建.出了执行点(右大括号),这个存储单元自动被释放.这些栈分配运算内置于处理器的指令集中,非常有效.但是,在写程序的时候,必须知道需要多少个存

Unity3D动态对象优化代码分享

具体解释请仔细看注释里已经讲解的很细致了,这里就不多废话了 代码如下: using UnityEngine; using System.Collections; using System.Collections.Generic; /// <summary> /// 动态对象优化 /// </summary> public class DynamicOptimization : MonoBehaviour { // Use this for initialization void S