九九热最新网址,777奇米四色米奇影院在线播放,国产精品18久久久久久久久久,中文有码视频,亚洲一区在线免费观看,国产91精品在线,婷婷丁香六月天

歡迎來到裝配圖網(wǎng)! | 幫助中心 裝配圖網(wǎng)zhuangpeitu.com!
裝配圖網(wǎng)
ImageVerifierCode 換一換
首頁 裝配圖網(wǎng) > 資源分類 > DOCX文檔下載  

CSharp擴展方法和擴展屬性

  • 資源ID:57159364       資源大小:37.69KB        全文頁數(shù):12頁
  • 資源格式: DOCX        下載積分:16積分
快捷下載 游客一鍵下載
會員登錄下載
微信登錄下載
三方登錄下載: 微信開放平臺登錄 支付寶登錄   QQ登錄   微博登錄  
二維碼
微信掃一掃登錄
下載資源需要16積分
郵箱/手機:
溫馨提示:
用戶名和密碼都是您填寫的郵箱或者手機號,方便查詢和重復下載(系統(tǒng)自動生成)
支付方式: 支付寶    微信支付   
驗證碼:   換一換

 
賬號:
密碼:
驗證碼:   換一換
  忘記密碼?
    
友情提示
2、PDF文件下載后,可能會被瀏覽器默認打開,此種情況可以點擊瀏覽器菜單,保存網(wǎng)頁到桌面,就可以正常下載了。
3、本站不支持迅雷下載,請使用電腦自帶的IE瀏覽器,或者360瀏覽器、谷歌瀏覽器下載即可。
4、本站資源下載后的文檔和圖紙-無水印,預覽文檔經(jīng)過壓縮,下載后原文更清晰。
5、試題試卷類文檔,如果標題沒有明確說明有答案則都視為沒有答案,請知曉。

CSharp擴展方法和擴展屬性

CSharp擴展方法擴展方法是實現(xiàn)新增類方法同時不改變類名稱的一種技術(shù)。可以部分的替代原本必須繼承類才能夠?qū)崿F(xiàn)的功能。但是,目前還不能擴展類的屬性,也不能在不繼承類的情況下而直接修改類方法。例如在A MVC Web Application中的,我們想快速了解某個Action上是否有某個Attribute. 那我們可以使用這樣的擴展方法:/ <summary>/ Gets the method./ </summary>/ <typeparam name="T">Type</typeparam>/ <param name="instance">The instance.</param>/ <param name="methodSelector">The method selector.</param>/ <returns>MethodInfo</returns>public static MethodInfo GetMethod<T>(this T instance, Expression<Func<T, object>> methodSelector) / it is not work all method return (MethodCallExpression)methodSelector.Body).Method;/ <summary>/ Gets the method./ </summary>/ <typeparam name="T"></typeparam>/ <param name="instance">The instance.</param>/ <param name="methodSelector">The method selector.</param>/ <returns>MethodInfo</returns>public static MethodInfo GetMethod<T>(this T instance, Expression<Action<T>> methodSelector) return (MethodCallExpression)methodSelector.Body).Method;/ <summary>/ Determines whether the specified member has attribute./ </summary>/ <typeparam name="TAttribute">The type of the attribute.</typeparam>/ <param name="member">The member.</param>/ <returns>/ <c>true</c> if the specified member has attribute; otherwise, <c>false</c>./ </returns>public static bool HasAttribute<TAttribute>( this MemberInfo member) where TAttribute : Attribute return GetAttributes<TAttribute>(member).Length > 0;/ <summary>/ Gets the attributes./ </summary>/ <typeparam name="TAttribute">The type of the attribute.</typeparam>/ <param name="member">The member.</param>/ <returns></returns>public static TAttribute GetAttributes<TAttribute>( this MemberInfo member) where TAttribute : Attribute var attributes = member.GetCustomAttributes(typeof(TAttribute), true); return (TAttribute)attributes;如何使用,請看下面的代碼,我們使用lambda表達式獲取某個方法,然后獲取其上面的Attribute:Factpublic void GetHttpPostAttributeFromCreateAction() / Arrange var controller = GetEmployeeController(new MemeoryEmployeeBoService(); /Act bool hasPostAttribute =controller.GetMethod(e => e.Create(new Employee() .HasAttribute<HttpPostAttribute>(); / Assert Assert.True(hasPostAttribute);擴展方法的實現(xiàn)1.首先,我們需要在項目中添加自己的一個類型,此處為ProjectExt,其中的方法與之前定義的方法大致上無區(qū)別,只是在方法中第一個參數(shù)前面添加了this關(guān)鍵字,this關(guān)鍵字必須是在方法參數(shù)中第一個參數(shù)的前面,不可以移位。view sourceprint?01.public static class ProjectExt02. 03. / <summary>04. / 向字符串追加字符05. / </summary>06. / <param name="obj">字符串</param>07. / <param name="AppendStr">需要追加的字符串</param>08. / <returns>追加完成的字符對象</returns>09. public static string AppendToLeft(this string obj,string AppendStr)10. 11. return AppendStr + obj;12. 13. 2.像在調(diào)用FCL本身類庫的方法一樣調(diào)用AppendToLeft,我們的代碼看起來更美麗整潔!view sourceprint?1.static void Main(string args)2.3. string Tel = "87763445"4. Console.WriteLine("Tel:"+ Tel.AppendToLeft("020-");5.輸出:020-87763445我們可以淺而易懂的看到兩者之間的區(qū)別,這就是擴展方法帶來的便捷之處,讓我們的代碼更加的整潔,在使用擴展方法的時候必須注意一下幾點:1.第一個參數(shù)之前必須有this關(guān)鍵字,不可變動2.在添加擴展方法的類型中,類型本身和類型所包含的方法必須是靜態(tài)的。3.由于這里是按類型識別,所以不應(yīng)該將擴展方法的第一個參數(shù)類型設(shè)為object,這樣會造成無論使用什么類型,都會擴展該方法。4.必須考慮將來FCL可能會添加相同的方法,如果FCL在以后的版本中添加了該方法,那么C#會優(yōu)先選擇FCL所定義的方法。最后的補充:擴展方法為什么要添加一個this在前面呢?這引用類型的特性有關(guān),this指向調(diào)用者本身,所以改變的也是調(diào)用者本身的實例,至于為什么在Visual Studio中能找到該方法,這是C#編輯器的功能,其中有一個搜索的過程,如果要使用不同命名空間下的擴展方法,請在代碼頂端using該命名空間。另外,由于結(jié)構(gòu)(struct)不能聲明為靜態(tài),但是擴展方法必須聲明在靜態(tài)類型之中,所以不能在結(jié)構(gòu)(struct)中聲明擴展方法,這點必須要注意!我們在開發(fā)經(jīng)常要使用Enum類型,今天我們用擴展方法來為Enum類型加入業(yè)務(wù)邏輯. 有以下的代碼: 1: / <summary> 2: / StorageProviders 3: / </summary> 4: Serializable 5: public enum StorageProviders 6: 7: / <summary> 8: / LuceneIo 9: / </summary> 10: LuceneIo = 0, 11: / <summary> 12: / LuceneVirtual 13: / </summary> 14: LuceneVirtual = 1 15: 然后寫一個擴展方法: 1: / <summary> 2: / StorageProvidersExtensions 3: / </summary> 4: public static class StorageProvidersExtensions 5: 6: / <summary> 7: / Determines whether the specified provider is virtual. 8: / </summary> 9: / <param name="provider">The provider.</param> 10: / <returns> 11: / <c>true</c> if the specified provider is virtual; otherwise, <c>false</c>. 12: / </returns> 13: public static bool IsVirtual(this StorageProviders provider) 14: 15: return provider = StorageProviders.LuceneVirtual; 16: 17: 好了,讓我們來看如何使用: 1: Test 2: public void TestEnumExtesnsionMethod() 3: 4: StorageProviders storageProviders = StorageProviders.LuceneVirtual; 5: Assert.IsTrue(storageProviders.IsVirtual(); 6: 為對象添加擴展屬性動態(tài)獲取數(shù)據(jù) 由于項目需要常常會遇到為某一個對象動態(tài)添加屬性的情況,而以前我的實現(xiàn)方式是創(chuàng)建一個字典用于存放對象實例和它的值,但是往往光這么做是不夠的,例如想在對象的某個屬性值改變的時候做點什么都要寫很多的代碼,所以想是不是能夠?qū)⑦@一類功能進行一下封裝。后來因為學習WPF的緣故,想到依賴屬性的思想和我需要的功能相近,但是又不能叫我把每一個想要添加擴展的對象類都去繼承DependencyObject吧,而且有些類是封閉的不能夠繼承,所以依賴屬性不能滿足我的需求。不過說到底依賴屬性還是個不錯的東西,接下來我們將實現(xiàn)一個類似的東西 - 擴展屬性。在實現(xiàn)擴展屬性時我也參考了依賴屬性的源碼,它的設(shè)計思想的確很“先進”。1.先來看看擴展屬性的使用方式:1: private static ExtendProperty InfoProperty = 2: ExtendProperty.RegisterProperty("Info", typeof(string), typeof(UserInfo),"you win"); 3: var user = new UserInfo() Age=21, Name="maxzhang" ; 4: 5: user.SetValue(InfoProperty, "hello"); 6: string rrr = (string)user.GetValue(InfoProperty);是不是看著特別像依賴屬性呢,往下面看:1: dynamic userDynamic = user.AsDynamic(); 2: rrr= userDynamic.Info; 3: userDynamic.Info = "1" 4: userDynamic.Age = 50; 5: rrr = userDynamic.Info;我為擴展屬性添加了動態(tài)性使對象屬性的創(chuàng)建和訪問更加方便,這里如果Info屬性在前面沒有用RegisterProperty方法定義過它會自動生成一個擴展屬性且添加屬性值.如果訪問了它的普通屬性屬性也是正常使用的。以上兩個例子中UserInfo類的定義是 public class UserInfo : ExtendObject public string Name set; get; public int Age set; get; ,你可能會問這不是和依賴屬性一樣嗎?只是把繼承DependencyObject換成了繼承你自己寫的ExtendObject 了。是的這樣看是差不多的,不過以上的情況還是有一個好處的就是我可以在任何項目里引用它。如果遇到了不能繼承的情況呢,其實這種情況有很多。接 public class UserInfo1 public string Nameset;get; 這個類不繼承任何類。解決它這里引入了新的擴展類型AttachObject :1: AttachObject user1Aobj = new AttachObject(user1); 2: var dyuser = user1Aobj.ToDynamicAttachObject(); 3: /var dyuser = user1.ToDynamicAttachObject(); 4: dyuser.Memo = "haha my name i's maxzhang." 5: rrr = dyuser.Memo;其實AttachObject 類型也是一個ExtendObject 可以把它看成是一個ExtendObject 的裝飾。2.下面我們來看看這些都是怎么實現(xiàn)的(1).ExtendProperty與依賴屬性類似,在ExtendProperty類中用了一個Dictionary<int,ExtendProperty>來存儲系統(tǒng)中要用到的擴展屬性,這樣實現(xiàn)也達到了節(jié)省內(nèi)存資源的目地。且這個類的構(gòu)造器是一個private的,這樣也就實現(xiàn)了一個單例模式,只有在RegisterProperty方法才能創(chuàng)造出一個ExtendProperty來.RegisterPropertypublic static ExtendProperty RegisterProperty(string propertyName, Type propertyType, Type ownerType,object defaultValue)var property = new ExtendProperty(propertyName, propertyType,ownerType);property.OverrideDefaultValue(ownerType, defaultValue);ExtendPropertysProvider.Set(property.GetHashCode(), property);return property;用GetHashCode來標示我們這個屬性的唯一性,這里我重寫了這個函數(shù)它的值是this.ownerType.GetHashCode()this.propertyName.GetHashCode(),也就是說用注冊這個屬性的類型和屬性的名稱確定了這個擴展屬性。我們看到OverrideDefaultValue這個方法它是用來重寫屬性的默認值的,在這個系統(tǒng)中如果某個對象的擴展屬性沒有賦過值或說沒有改變過,那么它應(yīng)該在訪問這個屬性的時候取得一個默認值而且這個默認值應(yīng)該是所有相同注冊類型的對象共有的,而在用普通屬性存儲的對象中我們實例化對象后會在每一個對象中保存相應(yīng)的默認值,這樣無疑是浪費了內(nèi)存。而且OverrideDefaultValue與AddOwner方法一起使用可以達到屬性繼承的目的。我們來看看AddOwner方法的實現(xiàn):AddOwnerpublic ExtendProperty AddOwner(Type ownerType,object defaultValue)int newOwnerHash = ownerType.GetHashCode() this.PropertyName.GetHashCode();if(defaultValue!=null)this.OverrideDefaultValue(ownerType, defaultValue);ExtendPropertysProvider.Set(newOwnerHash, this);return this;使用AddOwner方法我們就在原有的擴展屬性上添加了一個指向它的引用從而達到繼承的目地,怎么重寫屬性默認值呢?其實很簡單默認值在擴展屬性中保存在一個<type,object>的字典中通過不同的類型我們就可以訪問不同類型的相同屬性的默認值了。 (2).ExtendObject 這里ExtendObject就沒什么好說的了,原理就是其內(nèi)部有一個Dictionary<int, object> propertyValues 存儲著不同對象的值,用自身的GetHashCode 擴展屬性的HashCode 確定值的唯一性。ExtendObject的源碼,呵呵 public class ExtendObjectprotected Dictionary<int, object> propertyValues = new Dictionary<int, object>();private Type OwnerType = null;public ExtendObject()OwnerType = this.GetType();public override int GetHashCode()return base.GetHashCode();public virtual object GetOwner()return this;protected void AttachOwner(Type ownerType)this.OwnerType = ownerType;public bool IsExtendProperty(string propertyName)return !OwnerType.GetProperties().Any(p => p.Name = propertyName); ;protected ExtendProperty GetProperty(string name)int propertyKey = OwnerType.GetHashCode() name.GetHashCode();var property = ExtendPropertysProvider.Get(propertyKey);return property;public object GetValue(ExtendProperty property)int propertyHash = property.GetHashCode();int key = this.GetHashCode() propertyHash;object result = null;if (!propertyValues.TryGetValue(key, out result)result = property.GetDefaultValue(this.OwnerType);return result;public bool ClearValue(ExtendProperty property)bool result = false;int propertyHash = property.GetHashCode();int key = this.GetHashCode() propertyHash;if (propertyValues.Keys.Any(k => k = key)propertyValues.Remove(key);result = true;return result;public void SetValue(ExtendProperty property, object value)var changedItemArgs = new ExtendPropertyValueChangedArgs();int propertyHash = property.GetHashCode();int key = this.GetHashCode() propertyHash;if (propertyValues.Keys.Any(k => k = key)changedItemArgs.OldValue = propertyValueskey;propertyValueskey = value;elsechangedItemArgs.OldValue = null;propertyValues.Add(key, value);changedItemArgs.Item = GetOwner();changedItemArgs.PropertyType = property.PropertyType;changedItemArgs.PropertyName = property.PropertyName;changedItemArgs.NewValue = value;property.OnValueChanged(changedItemArgs);public bool ClearValue(string propertyName)var property = this.GetProperty(propertyName);if (property != null)return this.ClearValue(property);return false;public object GetValue(string propertyName)var property = this.GetProperty(propertyName);if (property != null)return this.GetValue(property);return null;public void SetValue(string propertyName, object value)var property = this.GetProperty(propertyName);if (property != null)this.SetValue(property, value);elsevar newProperty = ExtendProperty.RegisterProperty(propertyName, typeof(object), OwnerType);this.SetValue(newProperty, value);public ExtendDynamicObject AsDynamic()return new ExtendDynamicObject(this);不過這里還是有一個小小的技巧的就是OwnerType這個屬性和AttachOwner方法,默認的OwnerType屬性的值是擴展對象本身的Type,但是通過 AttachOwner方法我們可以改變這個屬性從而達到將不繼承自ExtendObject類型的對象裝飾成ExtendObject對象的目地。(3).也就是AttachObjectAttachObject類通過調(diào)用AttachOwner方法使用了這個技巧,同時把同樣為ExtendObject的對象的屬性統(tǒng)統(tǒng)都Copy過來.AttachObjectpublic class AttachObject : ExtendObjectprivate object owner;public AttachObject(object obj): base()owner = obj;if (owner is ExtendObject)Type ownerType = typeof(ExtendObject);FieldInfo fInfo = ownerType.GetField("propertyValues", BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Instance);var ownerValues = fInfo.GetValue(owner) as Dictionary<int, object>foreach (var v in ownerValues)this.propertyValues.Add(v.Key, v.Value);this.AttachOwner(owner.GetType();public override object GetOwner()return owner;public override int GetHashCode()return owner.GetHashCode();

注意事項

本文(CSharp擴展方法和擴展屬性)為本站會員(仙***)主動上傳,裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對上載內(nèi)容本身不做任何修改或編輯。 若此文所含內(nèi)容侵犯了您的版權(quán)或隱私,請立即通知裝配圖網(wǎng)(點擊聯(lián)系客服),我們立即給予刪除!

溫馨提示:如果因為網(wǎng)速或其他原因下載失敗請重新下載,重復下載不扣分。




關(guān)于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網(wǎng)版權(quán)所有   聯(lián)系電話:18123376007

備案號:ICP2024067431-1 川公網(wǎng)安備51140202000466號


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務(wù)平臺,本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對上載內(nèi)容本身不做任何修改或編輯。若文檔所含內(nèi)容侵犯了您的版權(quán)或隱私,請立即通知裝配圖網(wǎng),我們立即給予刪除!