zoukankan      html  css  js  c++  java
  • C#3.0实现变异赋值(Mutantic Assignment)

    话题从今天TerryLee关于MVC的一段代码说起:

    protected void Application_Start()
    {
        RouteTable.Routes.MapRoute(
            
    "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );
    }

    请注意new { controller = "Home", action = "Index", id = "" }参数,它是C#3.0引入的匿名类型。由于匿名类型是由编译器自动生成的类型,MapRoute在编译时并不知道其确切类型,而是在运行时通过反射解析其属性来获取信息。这种方式在语法上显得优雅简洁,它就是所谓的变异赋值(Mutantic Assignment)。

    平常我们修改一个form对象的属性需要若干的赋值语句:

    form.Text = “Hello World”;
    form.Top 
    = 100;
    form.Left 
    = 200;

    如果C#支持变异赋值,就可以像这样一句话搞定:

    form := new {Text = “Hello World”, Top = 100, Left = 200};


    这样是不是变得简洁优雅了?可惜现在C#还没有对变异赋值运算符 :=的支持。从更大的层面上,更可惜的是C#运算符重载依然有诸多限制,也没有像Boo语言支持的syntactic macro。期待在将来的C#中,我们能直接定制语言的语法,让代码更加优雅简洁。但现在,我们不得以退而求其次,只能尝试在C#3.0中用扩展方法模拟变异赋值功能:

    public static class Mutant
    {
        
    public static void  MAssign(this object target, object source)
        {
            
    foreach (PropertyInfo pi1 in source.GetType().GetProperties())
            {
                
    if (!pi1.CanRead) continue;

                PropertyInfo pi2 
    = target.GetType().GetProperty(pi1.Name, pi1.PropertyType);

                
    if (null == pi2 || !pi2.CanWrite) continue;

                pi2.SetValue(target, pi1.GetValue(source, 
    null), null);
            }
        }
    }

    上面对object类定义了MAssign扩展方法,通过反射获取和设置属性值模拟变异赋值。这样,我们就可以对任意对象进行变异赋值了:

    form.MAssign(new {Text = “Hello World”, Top = 100, Left = 200});
  • 相关阅读:
    Linkerd 2.10(Step by Step)—将 GitOps 与 Linkerd 和 Argo CD 结合使用
    Linkerd 2.10(Step by Step)—多集群通信
    Linkerd 2.10(Step by Step)—使用 Kustomize 自定义 Linkerd 的配置
    Linkerd 2.10(Step by Step)—控制平面调试端点
    Linkerd 2.10(Step by Step)—配置超时
    Linkerd 2.10(Step by Step)—配置重试
    Linkerd 2.10(Step by Step)—配置代理并发
    本地正常运行,线上环境诡异异常原因集合
    Need to invoke method 'xxx' declared on target class 'yyy', but not found in any interface(s) of the exposed proxy type
    alpine 安装常用命令
  • 原文地址:https://www.cnblogs.com/weidagang2046/p/1439643.html
Copyright © 2011-2022 走看看