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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Attribute鲜为人知的两个特性记录

發布時間:2025/3/15 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Attribute鲜为人知的两个特性记录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

??? Attribute作為一種標記在我們的.net中隨處可見,比如DatContract,DatMember,Serializable等等,各種用途的標記。是的我們的代碼更加簡潔,對于Attribute用好了,可以很好的簡化我們的開發,比如PostSharp的AOP實現就是一種基于Attribute的標記編譯時注入。在隨筆中有關于IOC,AOP利用Attribute標記簡化開發的實例。

?? 在使用Attribute時候發現了些鮮為人知的特性:

1:利用GetCustomAttributes傳入的Attribute返回得到包括派生類。

2:GetCustomAttributes每次返回的對象都是經過發射出來的沒有緩存。

?? 1:GetCustomAttributes傳入的Attribute返回得到包括派生類:

?????? 這里將采用一個測試類來驗證:

View Code [AttributeUsage(AttributeTargets.Class)]?
??public?class?TestImplementsAttribute?:?Attribute?
??{?
??????public?string?Name?
??????{?get;?set;?}?
??}

?

private?static?void?TestMutilpeImplements()?
{?
????var?type?=?typeof(Program);?
????var?attrs?=?type.GetCustomAttributes(typeof(TestImplementsAttribute),?false);?
????Console.WriteLine(string.Format("TestImplementsAttribute:({0})",attrs.Length));?
????foreach?(var?item?in?attrs)?
????{?
????????Console.WriteLine("??"?+?item.GetType().FullName);?
????}?
????attrs?=?type.GetCustomAttributes(typeof(SerializableAttribute),?false);?
????Console.WriteLine(string.Format("SerializableAttribute:({0})",?attrs.Length));?
????foreach?(var?item?in?attrs)?
????{?
????????Console.WriteLine("??"?+?item.GetType().FullName);?
????}?

????attrs?=?type.GetCustomAttributes(typeof(Attribute),?false);?
????Console.WriteLine(string.Format("(base?type)Attribute:({0})",?attrs.Length));?
????foreach?(var?item?in?attrs)?
????{?
????????Console.WriteLine("??"?+?item.GetType().FullName);?
????}?

}

輸出為:?

這里我們可以很清晰的看見當傳入Attribute類型時候返回包含了SerializableAttribute和TestImplementsAttribute兩個。

2:GetCustomAttributes每次返回的對象都是經過發射出來的沒有緩存:

測試代碼可以看出來,不是同一個地址引用:

private?static?void?TestAttributeActiver()?
??????{?
??????????var?type?=?typeof(Program);?
??????????var?attr1?=?type.GetCustomAttributes(typeof(TestImplementsAttribute),?false)[0];?
??????????var?attr2?=?type.GetCustomAttributes(typeof(TestImplementsAttribute),?false)[0];?
??????????Console.WriteLine(Object.ReferenceEquals(attr1,?attr2));????????????
??????}?

輸出值為false。?

我們在看看

.下面是 reflector的反編譯結果(Attribute.GetCustomAttributes):

View Code internal?static?unsafe?object[]?GetCustomAttributes(Module?decoratedModule,?int?decoratedMetadataToken,?int?pcaCount,?RuntimeType?attributeFilterType,?bool?mustBeInheritable,?IList?derivedAttributes)
{
????if?(decoratedModule.Assembly.ReflectionOnly)
????{
????????throw?new?InvalidOperationException(Environment.GetResourceString("Arg_ReflectionOnlyCA"));
????}
????MetadataImport?metadataImport?=?decoratedModule.MetadataImport;
????CustomAttributeRecord[]?customAttributeRecords?=?CustomAttributeData.GetCustomAttributeRecords(decoratedModule,?decoratedMetadataToken);
????Type?elementType?=?(((attributeFilterType?==?null)?||?attributeFilterType.IsValueType)?||?attributeFilterType.ContainsGenericParameters)???typeof(object)?:?attributeFilterType;
????if?((attributeFilterType?==?null)?&&?(customAttributeRecords.Length?==?0))
????{
????????return?(Array.CreateInstance(elementType,?0)?as?object[]);
????}
????object[]?attributes?=?Array.CreateInstance(elementType,?customAttributeRecords.Length)?as?object[];
????int?length?=?0;
????SecurityContextFrame?frame?=?new?SecurityContextFrame();
????frame.Push(decoratedModule.Assembly.InternalAssembly);
????Assembly?lastAptcaOkAssembly?=?null;
????for?(int?i?=?0;?i?<?customAttributeRecords.Length;?i++)
????{
????????bool?flag2;
????????bool?flag3;
????????object?obj2?=?null;
????????CustomAttributeRecord?caRecord?=?customAttributeRecords[i];
????????RuntimeMethodHandle?ctor?=?new?RuntimeMethodHandle();
????????RuntimeType?attributeType?=?null;
????????int?namedArgs?=?0;
????????IntPtr?signature?=?caRecord.blob.Signature;
????????IntPtr?blobEnd?=?(IntPtr)?(((void*)?signature)?+?caRecord.blob.Length);
????????if?(FilterCustomAttributeRecord(caRecord,?metadataImport,?ref?lastAptcaOkAssembly,?decoratedModule,?decoratedMetadataToken,?attributeFilterType,?mustBeInheritable,?attributes,?derivedAttributes,?out?attributeType,?out?ctor,?out?flag2,?out?flag3))
????????{
????????????if?(!ctor.IsNullHandle())
????????????{
????????????????ctor.CheckLinktimeDemands(decoratedModule,?decoratedMetadataToken);
????????????}
????????????RuntimeConstructorInfo.CheckCanCreateInstance(attributeType,?flag3);
????????????if?(flag2)
????????????{
????????????????obj2?=?CreateCaObject(decoratedModule,?ctor,?ref?signature,?blobEnd,?out?namedArgs);
????????????}
????????????else
????????????{
????????????????obj2?=?attributeType.TypeHandle.CreateCaInstance(ctor);
????????????????if?(Marshal.ReadInt16(signature)?!=?1)
????????????????{
????????????????????throw?new?CustomAttributeFormatException();
????????????????}
????????????????signature?=?(IntPtr)?(((void*)?signature)?+?2);
????????????????namedArgs?=?Marshal.ReadInt16(signature);
????????????????signature?=?(IntPtr)?(((void*)?signature)?+?2);
????????????}
????????????for?(int?j?=?0;?j?<?namedArgs;?j++)
????????????{
????????????????string?str;
????????????????bool?flag4;
????????????????Type?type3;
????????????????object?obj3;
????????????????IntPtr?ptr1?=?caRecord.blob.Signature;
????????????????GetPropertyOrFieldData(decoratedModule,?ref?signature,?blobEnd,?out?str,?out?flag4,?out?type3,?out?obj3);
????????????????try
????????????????{
????????????????????if?(flag4)
????????????????????{
????????????????????????if?((type3?==?null)?&&?(obj3?!=?null))
????????????????????????{
????????????????????????????type3?=?(obj3.GetType()?==?typeof(RuntimeType))???typeof(Type)?:?obj3.GetType();
????????????????????????}
????????????????????????RuntimePropertyInfo?property?=?null;
????????????????????????if?(type3?==?null)
????????????????????????{
????????????????????????????property?=?attributeType.GetProperty(str)?as?RuntimePropertyInfo;
????????????????????????}
????????????????????????else
????????????????????????{
????????????????????????????property?=?attributeType.GetProperty(str,?type3,?Type.EmptyTypes)?as?RuntimePropertyInfo;
????????????????????????}
????????????????????????RuntimeMethodInfo?setMethod?=?property.GetSetMethod(true)?as?RuntimeMethodInfo;
????????????????????????if?(setMethod.IsPublic)
????????????????????????{
????????????????????????????setMethod.MethodHandle.CheckLinktimeDemands(decoratedModule,?decoratedMetadataToken);
????????????????????????????setMethod.Invoke(obj2,?BindingFlags.Default,?null,?new?object[]?{?obj3?},?null,?true);
????????????????????????}
????????????????????}
????????????????????else
????????????????????{
????????????????????????(attributeType.GetField(str)?as?RtFieldInfo).InternalSetValue(obj2,?obj3,?BindingFlags.Default,?Type.DefaultBinder,?null,?false);
????????????????????}
????????????????}
????????????????catch?(Exception?exception)
????????????????{
????????????????????throw?new?CustomAttributeFormatException(string.Format(CultureInfo.CurrentUICulture,?Environment.GetResourceString(flag4???"RFLCT.InvalidPropFail"?:?"RFLCT.InvalidFieldFail"),?new?object[]?{?str?}),?exception);
????????????????}
????????????}
????????????if?(!signature.Equals(blobEnd))
????????????{
????????????????throw?new?CustomAttributeFormatException();
????????????}
????????????attributes[length++]?=?obj2;
????????}
????}
????frame.Pop();
????if?((length?==?customAttributeRecords.Length)?&&?(pcaCount?==?0))
????{
????????return?attributes;
????}
????if?(length?==?0)
????{
????????Array.CreateInstance(elementType,?0);
????}
????object[]?destinationArray?=?Array.CreateInstance(elementType,?(int)?(length?+?pcaCount))?as?object[];
????Array.Copy(attributes,?0,?destinationArray,?0,?length);
????return?destinationArray;
}

在這里我們可以見數組的創建CreateInstance等等。

?? 同時可以參見老趙前輩以前的關于Attribute反射的一次失敗的嘗試(上):原來GetCustomAttributes方法每次都返回新的實例和一次失敗的嘗試(下):無法使用泛型的Attribute。

?? 不知道為什么在Attribute參數的檢查是在我們的編譯時期,參數必須是常量表達式,卻在這里需要每次反射。

?? 本篇隨筆只是個人使用心得記錄,請勿拍磚。

總結

以上是生活随笔為你收集整理的Attribute鲜为人知的两个特性记录的全部內容,希望文章能夠幫你解決所遇到的問題。

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

主站蜘蛛池模板: 天天操操| 久热超碰 | 一级做a免费 | 亚洲一区二区三区在线免费观看 | 午夜免费视频观看 | 国产精品无码av无码 | 午夜久久电影 | 天堂少妇| 超碰2| 国产三级三级在线观看 | 日韩精品一 | 国产精品久久久久久久久久 | wwwxxx黄色片 | 丁香花激情网 | 男人的天堂网在线 | 久久中文字幕视频 | 大尺度av | 久草福利资源 | 嫩草www| 精品无人区无码乱码毛片国产 | 欧美性猛交xxxx乱大交俱乐部 | 天天澡天天狠天天天做 | 亚洲一级av无码毛片精品 | 欧美一线高本道 | 黄瓜视频污在线观看 | 成年人网站免费观看 | 天天婷婷 | 香港三日本三级少妇66 | 久久久久人 | 亚洲国产精品99久久久久久久久 | 99久久精品一区二区三区 | 亚洲精品视频一区二区三区 | 超碰成人免费在线 | 色综合久久88色综合天天免费 | 朋友人妻少妇精品系列 | 欧美性69 | 在线免费一级片 | 欧美三根一起进三p | 你懂的在线观看网址 | 超碰77 | 成年人看的网站 | 国产精品久久久一区 | 乱妇乱女熟妇熟女网站 | 麻豆网页 | 邪恶久久 | www.777奇米影视 | 秘密爱大尺度做爰呻吟 | 欧美老女人性生活视频 | 污av| 成年人免费小视频 | 日韩人成| 四虎在线视频免费观看 | 日韩欧美不卡 | 图片区偷拍区小说区 | 亚洲国产成人精品激情在线 | 久久叉 | hd丰满圆润的女人hd | 亚洲综合图区 | 在线观看h网站 | 多毛的亚洲人毛茸茸 | 亚洲综合一区在线 | 色综合五月 | 亚洲资源网站 | 温柔少妇的高潮呻吟 | 精品一区二区三区四区五区六区 | 日本一区视频在线 | 成人ay| 不卡av在线免费观看 | www.99re.| 桃花岛影院 | 超碰1000 | 亚洲天堂久久久 | 99re这里只有精品在线 | av色综合| 国产精品无码成人网站视频 | 自拍偷在线精品自拍偷无码专区 | 免费观看在线高清 | 91免费视频入口 | 奇米色影视 | 销魂奶水汁系列小说 | 日韩成人动漫在线观看 | 日韩黄色大全 | 男女操操 | 欧美精品啪啪 | 天堂在线亚洲 | www.久久国产 | 伊人青青久久 | 屁屁影院一区二区三区 | 天天射天天| 国产一区二区播放 | 免费国产视频 | 性网址| 九九色在线 | 国产噜噜噜噜噜久久久久久久久 | 亚洲日批视频 | 免费一级suv好看的国产网站 | 亚洲欧美综合 | 日韩aⅴ片| 成人激情开心 |