如何修改 匿名类型 中的属性值 ?
生活随笔
收集整理的這篇文章主要介紹了
如何修改 匿名类型 中的属性值 ?
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
咨詢區
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?}點評區
這個題目其實很有意思,雖然語言和框架設計者用了各種限制來阻止我們做一些事情,其實都有化解的方法,所以并沒有永恒的不可變,最徹底的還可以通過修改內存地址變更,不是嘛~
總結
以上是生活随笔為你收集整理的如何修改 匿名类型 中的属性值 ?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Win11新版右键菜单用不惯?一键切换回
- 下一篇: 微信重磅更新!这个功能等了 7 年