如何修改 匿名类型 中的属性值 ?

咨询区

  • Leo Vo

我有下面一段代码:

var output = new
{NetSessionId = string.Empty
};foreach (var property in output.GetType().GetProperties())
{property.SetValue(output, "Test", null);
}

代码运行后,它会抛出如下异常:

Property set method not found

我想知道如何给这个 匿名类型 的属性赋值?

回答区

  • Alex

从 MSDN :https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/types/anonymous-types 的描述来看,理论上 匿名类型 是不可变的,一旦定义好之后,你是无法对它重新赋值。

但我想提醒的是,其实并没有所谓永恒的不可变,你要是真想变,肯定是有办法的,比如下面的 匿名类

var myAnonInstance = new{FirstField = "Hello",AnotherField = 30,};

当你用 ILSpy 反编译后代码如下:

internal sealed class <>f__AnonymousType0<<FirstField>j__TPar, <AnotherField>j__TPar>{[DebuggerBrowsable(DebuggerBrowsableState.Never)]private readonly <FirstField>j__TPar<FirstField> i__Field;[DebuggerBrowsable(DebuggerBrowsableState.Never)]private readonly <AnotherField>j__TPar<AnotherField> i__Field;public <FirstField>j__TPar FirstField{get{return < FirstField > i__Field;}}public <AnotherField>j__TPar AnotherField{get{return < AnotherField > i__Field;}}}

可以看到,底层的字段其实是有默认规范的: <xxxxx>i__Field, 这里的 xxxxx 就是属性名字,接下来就可以用 反射 来修改背后的字段即可,参考代码如下:

public static class AnonymousObjectMutator
{private const BindingFlags FieldFlags = BindingFlags.NonPublic | BindingFlags.Instance;private static readonly string[] BackingFieldFormats = { "<{0}>i__Field", "<{0}>" };public static T Set<T, TProperty>(this T instance,Expression<Func<T, TProperty>> propExpression,TProperty newValue) where T : class{var pi = (propExpression.Body as MemberExpression).Member;var backingFieldNames = BackingFieldFormats.Select(x => string.Format(x, pi.Name)).ToList();var fi = typeof(T).GetFields(FieldFlags).FirstOrDefault(f => backingFieldNames.Contains(f.Name));if (fi == null)throw new NotSupportedException(string.Format("Cannot find backing field for {0}", pi.Name));fi.SetValue(instance, newValue);return instance;}
}

然后你可以这样使用。

public static void Main(params string[] args)
{var myAnonInstance = new { FirstField = "Hello", AnotherField = 30, };Console.WriteLine(myAnonInstance);myAnonInstance.Set(x => x.FirstField, "Hello SO").Set(x => x.AnotherField, 42);Console.WriteLine(myAnonInstance);
}

输出结果:

{ FirstField = Hello, AnotherField = 30 }
{ FirstField = Hello SO, AnotherField = 42 }

点评区

这个题目其实很有意思,虽然语言和框架设计者用了各种限制来阻止我们做一些事情,其实都有化解的方法,所以并没有永恒的不可变,最彻底的还可以通过修改内存地址变更,不是嘛~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/293797.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SWF反编译神器ASV2013功能展示(下)

动作脚本菜单动作脚本-查看元件类动作脚本-编辑AS3常量池动作脚本-ASV内部ABC数据浏览器窗口菜单 选项菜单-帧视图选项 选项菜单-预览窗口选项选项菜单-时间线视图选项选项菜单-库视图选项 选项菜单-动作脚本视图选项实用工具菜单 关于对话框 转载于:https://blog.51cto.com/as…

Andorid之taskAffinity 和 FLAG_ACTIVITY_NEW_TASK

taskAffinity 和 FLAG_ACTIVITY_NEW_TASK都是和activity启动时是否需要新建一个task有关&#xff0c;我们分四种情况看一下这两个标志对启动activity的影响&#xff1a;(前提&#xff1a;从MainActivity中启动ActivityA) 1)、两个标志都不设置 2)、有FLAG_ACTIVITY_NEW_TASK …

【项目 报错】 项目启动,内存溢出 可能出现的各种报错

内存溢出可能有如下的错误&#xff1a; 错误1&#xff1a; java.lang.OutOfMemoryError: PermGen space 错误2&#xff1a; Exception in thread "http-apr-8080-exec-2" 出现如上的错误&#xff0c;解决方法如下&#xff1a; 1.双击Tomcat 2.点击open launch config…

杨中科的.NET 6新书的出版进度汇报

各位朋友好&#xff0c;我有3个月没发公众号了&#xff0c;今天打扰大家一下&#xff0c;不好意思。最近这3个月&#xff0c;我在忙着给我的.NET 6新书收尾&#xff0c;并且在.NET 6正式版发布后&#xff0c;我把书中用.NET 6 预览版编写的内容在.NET 6正式版中又验证了一遍&am…

2021,如何找到适合自己的圈子?

全世界只有3.14 % 的人关注了爆炸吧知识蔡康永分享过这样一段话&#xff1a;“小S的个性本身就是很乐天&#xff0c;很有活力&#xff0c;她这个朋友让我觉得活着是一件很值得、很舒服、很有趣的事。而有的人会让我觉得活着很没劲&#xff0c;碰到他会把我的能量都吸走”。你和…

Android之用Intent.FLAG_ACTIVITY_CLEAR_TOP解决界面重复拉起问题

今天遇到了一个问题: 就是界面在服务拉起来用的Intent.FLAG_ACTIVITY_NEW_TASK导致登录界面拉起很多次,登录还要登录,主要是之前的activity没有关闭 用it.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_CLEAR_TOP)解决。 A - B - C 当 B - A - B 跳转的时…

抓图实例

//调用动态链接库gdi32.dll[ System.Runtime.InteropServices.DllImportAttribute ( "gdi32.dll" ) ]private static extern bool BitBlt (IntPtr hdcDest , //目标设备的句柄int nXDest , // 目标对象的左上角的X坐标int nYDest , // 目标对象的左上角的X坐标int nW…

代码Review发现问题

FrmMain.cs中存在问题 1. int i0 设定为了全局常量且未在类顶部&#xff0c;出现问题时不好查找 i 属于常用临时变量&#xff0c;设定全局变量容易引起混乱 2.定义的全局变量但仅在一处方法中使用&#xff0c;定义全局变量过多 3.变量名及控件名等意义不明确又缺少注释&#xf…

I/O多路转接之poll——基于TCP协议

1. 函数a. 参数&#xff1a;&#xff08;1&#xff09;fds:是一个struct pollfd结构类型的指针&#xff0c;指向用于存放需要检测状态的Socket描述符&#xff1b;每当调用这个函数之后&#xff0c;系统不会清空这个数组&#xff0c;操作起来比较方便&#xff1b;特别是对于sock…

Android之 FLAG_ACTIVITY_CLEAR_TASK

FLAG_ACTIVITY_CLEAR_TASK :如果在调用Context.startActivity时传递这个标记&#xff0c;将会导致任何用来放置该activity的已经存在的task里面的已经存在 的activity先清空&#xff0c;然后该activity再在该task中启动&#xff0c;也就是说&#xff0c;这个新启动的activity变…

C# 日志管理框架:Common.Logging和log4net

01—DLL引用‍common logging是一个通用日志接口框架&#xff0c;log4net是一个强大的具体实现框架. common logging可以把输出连接到其他非log类上, 如EntLib的日志、NLog等‍‍‍‍‍‍‍‍‍‍‍‍‍‍项目中需要引入的DLL:Common.Logging.dllCommon.Logging.Core.dllCommon…

boost常用记录

1.BOOST_FOREACH 经常会遍历容器&#xff0c;写for/while循环到手痛&#xff0c;使用BOOST_FOREACH可以减少我们的工作。支持容器vector/list/set/deque/stack/queue#include <boost/foreach.hpp> BOOST_FOREACH(value,container){ //遍历每个元素 } 例子&#xff1a; ve…

Cacti迁移RRA数据迁移脚本

迁移程序和数据库完成后&#xff0c;默认的rra数据并不能出图&#xff0c; 需要从旧机器上将rra数据导出到新机器上&#xff0c;附上脚本 #导出rra数据 #!/bin/bash rrddump"/usr/bin/rrdtool dump" xmldir/data/rraxml/ rradir/var/www/html/cacti/rra/ for file in…

Android之FLAG_ACTIVITY_SINGLE_TOP

FLAG_ACTIVITY_SINGLE_TOP :如果当前栈顶的activity就是要启动的activity,则不会再启动一个新的activity实例&#xff1a;我们有一个apk&#xff0c;apk中包含两个Activity:MainActivity和ActivityA&#xff0c;点击MainActivity启动ActivityA,点击ActivityA还是启动ActivityA&…

我开发了一个对.NET程序进行瘦身的工具

我开发了一个对.Net程序瘦身的工具&#xff0c;可以把被引用但是没有被使用的程序集删除。我用它把一个.Net core程序从147兆瘦身到59.5兆。.NET中发布程序的时候有对程序集进行剪裁的功能&#xff0c;但是那个功能只能做静态检查。比如我们的项目使用了A程序集&#xff0c;A程…

三联竟出了这么赞的杂志!各领域佼佼者畅所欲言,为少年建立思维判断体系!

▲点击查看很多中国小孩的成长是断层的。10岁前被视作可爱稚子&#xff0c;被大人护着走&#xff1b;18岁猛然被定义为成年人&#xff0c;要选择大学、专业&#xff0c;开始面对感情。中间的人生呢&#xff1f;“你是个学生&#xff0c;学习是本职&#xff0c;现在谈什么人生&a…

源码lnmp

1、准备工作&#xff1a;配置yum源安装开发工具、编译工具gcc gcc-c make配置固定ip地址 关闭iptables selinuxnetstat -anpult | grep :3306netstat -anpult | grep :80若端口占用kill并service httpd stop ; chkconfig httpd offservice mysqld stop ; chkconfig mysqld off …

IIS书籍

book.51cto.com/art/200908/146040.htm

基于'sessionStorage'与'userData'的类session存储

Storage.js&#xff1a; 注意&#xff1a;此版本实现的存储在符合Web存储标准(ie8及ie8以上的版本与其他主流浏览器)的情况下与session的周期一致,但在页面不关闭的情况下没有过期时间,ie7及以下版本则默认是永久保存&#xff0c;但可以通过预留的方法setMaxAge(Number age)来设…