原創|行業資訊|編輯:鄭恭琳|2015-08-28 12:00:07.000|閱讀 829 次
概述:下面列出程序員在C#編程生涯中最喜歡的15個被隱藏的功能,包括完整的解釋和代碼示例。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
有關C#中15大隱藏的頂級功能的第一個帖子是出現在Automate The Planet上。下面列出程序員在C#編程生涯中最喜歡的被隱藏的C#功能,當然包括完整的解釋和代碼示例。
ObsoleteAttribute適用于除組件,模塊,參數和返回值的所有程序元素。標記過時元素,并通知用戶該元件將在產品的未來版本中刪除。
Message屬性包含一個當assignee屬性后將顯示的字符串。
IsError-設置為true,如果在代碼中使用目標屬性。
public static class ObsoleteExample { // Mark OrderDetailTotal As Obsolete. [ObsoleteAttribute("This property (DepricatedOrderDetailTotal) is obsolete. Use InvoiceTotal instead.", false)] public static decimal OrderDetailTotal { get { return 12m; } } public static decimal InvoiceTotal { get { return 25m; } } // Mark CalculateOrderDetailTotal As Obsolete. [ObsoleteAttribute("This method is obsolete. Call CalculateInvoiceTotal instead.", true)] public static decimal CalculateOrderDetailTotal() { return 0m; } public static decimal CalculateInvoiceTotal() { return 1m; } }
如果我們在代碼中使用上述類,系統將給出錯誤或警告。
Console.WriteLine(ObsoleteExample.OrderDetailTotal); Console.WriteLine(); Console.WriteLine(ObsoleteExample.CalculateOrderDetailTotal());
官方文檔:
DefaultValueAttribute指定了屬性的默認值。你可以創建DefaultValueAttribute為任何價值,成員的默認值通常是它的初始值。
該屬性不會導致成員被自動指定的值初始化。因此,你必須在代碼中設置初始值。
public class DefaultValueAttributeTest { public DefaultValueAttributeTest() { // Use the DefaultValue propety of each property to actually set it, via reflection. foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(this)) { DefaultValueAttribute attr = (DefaultValueAttribute)prop.Attributes[typeof(DefaultValueAttribute)]; if (attr != null) { prop.SetValue(this, attr.Value); } } } [DefaultValue(25)] public int Age { get; set; } [DefaultValue("Anton")] public string FirstName { get; set; } [DefaultValue("Angelov")] public string LastName { get; set; } public override string ToString() { return string.Format("{0} {1} is {2}.", this.FirstName, this.LastName, this.Age); } }
Auto-implemented屬性在類中通過反射構造函數初始化。代碼通過類的所有屬性進行迭代,并且如果DefaultValueAttribute存在,就將它們設置為默認值。
官方文檔:
確定成員是否以及如何顯示在調試器變量窗口。
public static class DebuggerBrowsableTest { private static string squirrelFirstNameName; private static string squirrelLastNameName; // The following DebuggerBrowsableAttribute prevents the property following it // from appearing in the debug window for the class. [DebuggerBrowsable(DebuggerBrowsableState.Never)] public static string SquirrelFirstNameName { get { return squirrelFirstNameName; } set { squirrelFirstNameName = value; } } [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)] public static string SquirrelLastNameName { get { return squirrelLastNameName; } set { squirrelLastNameName = value; } } }
如果你在代碼中使用示例類,那么嘗試通過調試器(F11)執行。
DebuggerBrowsableTest.SquirrelFirstNameName = "Hammy"; DebuggerBrowsableTest.SquirrelLastNameName = "Ammy";
官方文檔:
?? Operator是程序猿最喜歡的C#隱藏功能之一,經常在代碼里用到它。
如果左邊的操作數不為空,?? Operator返回左邊的操作數,,否則將返回右邊的。可空類型可以包含一個值,也可以是不確定的。當可空類型分配給非可空類型時?? Operator定義返回默認值。
int? x = null; int y = x ?? -1; Console.WriteLine("y now equals -1 because x was null => {0}", y); int i = DefaultValueOperatorTest.GetNullableInt() ?? default(int); Console.WriteLine("i equals now 0 because GetNullableInt() returned null => {0}", i); string s = DefaultValueOperatorTest.GetStringValue(); Console.WriteLine("Returns 'Unspecified' because s is null => {0}", s ?? "Unspecified");
官方文檔:
Curry-在數學和計算機科學中,柯里化(Currying)是把接受多個參數的函數變換成接受一個單一參數(最初函數的第一個參數)的函數,并且返回接受余下的參數且返回結果的新函數的技術。
要想通過C#實現,就要用到Curry擴展方法。
public static class CurryMethodExtensions { public static Func<A, Func<B, Func<C, R>>> Curry<A, B, C, R>(this Func<A, B, C, R> f) { return a => b => c => f(a, b, c); } }
擴展方法的使用一開始是有點勢不可擋的。
Func<int, int, int, int> addNumbers = (x, y, z) => x + y + z; var f1 = addNumbers.Curry(); Func<int, Func<int, int>> f2 = f1(3); Func<int, int> f3 = f2(4); Console.WriteLine(f3(5));
不同函數的返回類型可通過var關鍵字進行交換。
官方文檔:
Partial - 在計算機科學中,部分應用程序(或部分功能的應用程序)是指固定的一些參數的函數,產生另一種更小參數數量功能的過程。
public static class CurryMethodExtensions { public static Func<C, R> Partial<A, B, C, R>(this Func<A, B, C, R> f, A a, B b) { return c => f(a, b, c); } }
Partial的擴展方法比Curry的更簡單直觀。
Func<int, int, int, int> sumNumbers = (x, y, z) => x + y + z; Func<int, int> f4 = sumNumbers.Partial(3, 4); Console.WriteLine(f4(5));
同樣,不同類型的代理可通過var關鍵字來聲明。
官方文檔:
Weak Reference允許垃圾收集器收集對象,同時還允許應用程序訪問的對象。如果需要該對象,仍可通過強引用獲取,并防止它被收集。
WeakReferenceTest hugeObject = new WeakReferenceTest(); hugeObject.SharkFirstName = "Sharky"; WeakReference w = new WeakReference(hugeObject); hugeObject = null; GC.Collect(); Console.WriteLine((w.Target as WeakReferenceTest).SharkFirstName);
如果垃圾收集沒有被明確調用,跟有可能弱引用仍可被分配。
官方文檔:
使用延遲初始化推遲創建大型或資源密集型對象,或執行資源密集型任務,特別是在程序的生命周期內可能不會發生這樣的創建或執行。
public abstract class ThreadSafeLazyBaseSingleton<T> where T : new() { private static readonly Lazy<T> lazy = new Lazy<T>(() => new T()); public static T Instance { get { return lazy.Value; } } }
官方文檔:
BigInteger類型是一個不可變型,代表一個任意大的整數,其值在理論上是沒有上限和下限的。這種類型不同于其它.NET Framework中的整型,它們有MINVALUE和MaxValue屬性表示的范圍。
注意:由于BigInteger的類型是不可改變并且沒有上限或下限的,因此任何引起BigInteger值增長過大的操作都可能拋出OutOfMemoryException異常。
string positiveString = "91389681247993671255432112000000"; string negativeString = "-90315837410896312071002088037140000"; BigInteger posBigInt = 0; BigInteger negBigInt = 0; posBigInt = BigInteger.Parse(positiveString); Console.WriteLine(posBigInt); negBigInt = BigInteger.Parse(negativeString); Console.WriteLine(negBigInt);
官方文檔:
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn