日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/4 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 如何修改 匿名类型 中的属性值 ? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

咨詢區

  • 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?}

點評區

這個題目其實很有意思,雖然語言和框架設計者用了各種限制來阻止我們做一些事情,其實都有化解的方法,所以并沒有永恒的不可變,最徹底的還可以通過修改內存地址變更,不是嘛~

總結

以上是生活随笔為你收集整理的如何修改 匿名类型 中的属性值 ?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。