Top 15 不起眼却有大作用的 .NET功能集
目录
1. ObsoleteAttribute
2. 设置默认值属性: DefaultValueAttribute
3. DebuggerBrowsableAttribute
4. ??运算符
5. Curry 及 Partial 方法
6. WeakReference
7. Lazy
8. BigInteger
9. 非官方关键字:__arglist __reftype __makeref __refvalue
10. Environment.NewLine
11. ExceptionDispatchInfo
12. Environment.FailFast
13. Debug.Assert, Debug.WriteIf 及 Debug.Indent
14. Parallel.For 及 Parallel.Foreach
15. IsInfinity方法
本文介绍了.Net 常被忽略,但却非常有用户的15个功能,包含ObsoleteAttribute,DefaultValueAttribute,DebuggerBrowsableAttribute,?运算符,Curry 及 Partial 方法…
1. ObsoleteAttribute
ObsoleteAttribute: 可适用于除程序集、模块、参数或返回值以外的所有程序元素。将元素标记为 Obsolete 可实现通知用户的功能,表明该元素在产品之后的新版本中会被移除。
Message属性包含一个字符串,可获取变通方法消息,是对可选程序元素的说明。
IsError属性:是Bool 类型,如果将值设为“True”,则编译器会将使用已过时的程序元素视为错误。
1: public static class ObsoleteExample
2: {
3: // Mark OrderDetailTotal As Obsolete.
4: [ObsoleteAttribute("This property (DepricatedOrderDetailTotal) is obsolete. Use InvoiceTotal instead.", false)]
5: public static decimal OrderDetailTotal
6: {
7: get
8: {
9: return 12m;
10: }
11: }
12:
13: public static decimal InvoiceTotal
14: {
15: get
16: {
17: return 25m;
18: }
19: }
20:
21: // Mark CalculateOrderDetailTotal As Obsolete.
22: [ObsoleteAttribute("This method is obsolete. Call CalculateInvoiceTotal instead.", true)]
23: public static decimal CalculateOrderDetailTotal()
24: {
25: return 0m;
26: }
27:
28: public static decimal CalculateInvoiceTotal()
29: {
30: return 1m;
31: }
32: }
如果运行程序,编译器就会报错以及Warning。
1: Console.WriteLine(ObsoleteExample.OrderDetailTotal);
2: Console.WriteLine();
3: Console.WriteLine(ObsoleteExample.CalculateOrderDetailTotal());

2. 通过“DefaultValueAttribute”属性可设置缺省值
DefaultValueAttribute 指定属性的默认值。可以使用任何值创建 DefaultValueAttribute。成员的默认值通常是其初始值。可视化设计器可以使用默认值重置成员的值。代码生成器也可使用默认值确定是否 为成员生成代码,但是必须在成员函数中设置初始值。
1: public class DefaultValueAttributeTest
2: {
3: public DefaultValueAttributeTest()
4: {
5: // Use the DefaultValue propety of each property to actually set it, via reflection.
6: foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(this))
7: {
8: DefaultValueAttribute attr = (DefaultValueAttribute)prop.Attributes[typeof(DefaultValueAttribute)];
9: if (attr != null)
10: {
11: prop.SetValue(this, attr.Value);
12: }
13: }
14: }
15:
16: [DefaultValue(25)]
17: public int Age { get; set; }
18:
19: [DefaultValue("Anton")]
20: public string FirstName { get; set; }
21:
22: [DefaultValue("Angelov")]
23: public string LastName { get; set; }
24:
25: public override string ToString()
26: {
27: return string.Format("{0} {1} is {2}.", this.FirstName, this.LastName, this.Age);
28: }
29: }
3. DebuggerBrowsableAttribute
表示成员是否在Debugger 变量窗口显示以及如何显示。
1: public static class DebuggerBrowsableTest
2: {
3: private static string squirrelFirstNameName;
4: private static string squirrelLastNameName;
5:
6: // The following DebuggerBrowsableAttribute prevents the property following it
7: // from appearing in the debug window for the class.
8: [DebuggerBrowsable(DebuggerBrowsableState.Never)]
9: public static string SquirrelFirstNameName
10: {
11: get
12: {
13: return squirrelFirstNameName;
14: }
15: set
16: {
17: squirrelFirstNameName = value;
18: }
19: }
20:
21: [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
22: public static string SquirrelLastNameName
23: {
24: get
25: {
26: return squirrelLastNameName;
27: }
28: set
29: {
30: squirrelLastNameName = value;
31: }
32: }
33: }
逐步调试程序时,就会发现代码会一直在执行:
1: DebuggerBrowsableTest.SquirrelFirstNameName = "Hammy";
2: DebuggerBrowsableTest.SquirrelLastNameName = "Ammy";
4. ??操作符
?? 运算符称作 null 合并运算符。如果此运算符的左操作数不为 null,则此运算符将返回左操作数;否则返回右操作数,如果在尝试将可以为null 值的类型分配给不可以为null值的类型时,没有使用??运算符,则会生成编译时的错误。如果使用强制转换,且当前未定义可以为 null 值的类型,则会引发 InvalidOperationException 异常。
1: int? x = null;
2: int y = x ?? -1;
3: Console.WriteLine("y now equals -1 because x was null => {0}", y);
4: int i = DefaultValueOperatorTest.GetNullableInt() ?? default(int);
5: Console.WriteLine("i equals now 0 because GetNullableInt() returned null => {0}", i);
6: string s = DefaultValueOperatorTest.GetStringValue();
7: Console.WriteLine("Returns 'Unspecified' because s is null => {0}", s ?? "Unspecified");
5. Curry 及 Partial 方法
Curry 方法是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。
1: public static class CurryMethodExtensions
2: {
3: public static Func<A, Func<B, Func<C, R>>> Curry<A, B, C, R>(this Func<A, B, C, R> f)
4: {
5: return a => b => c => f(a, b, c);
6: }
7: }
如果无法确定成员函数的返回类型可使用Var执行。
Partial—Partial类型允许我们将一个类、接口或结构分成好几个部分,分别实现在几个不同的.cs 文件中。关键字partial是一个上下文关键字,只有和class、struct、interface放在一起时才有关键字的含义。因此partial 的引入不会影响现有代码中名称为partial的变量。
1: public static class CurryMethodExtensions
2: {
3: public static Func<C, R> Partial<A, B, C, R>(this Func<A, B, C, R> f, A a, B b)
4: {
5: return c => f(a, b, c);
6: }
7: }
6. WeakReference
Weak Reference 表示类型化弱引用,即在引用对象的同时仍然允许垃圾回收来回收该对象。如果你想使用该引用,可以设置为强引用类型,保证该对象不被回收。
1: WeakReferenceTest hugeObject = new WeakReferenceTest();
2: hugeObject.SharkFirstName = "Sharky";
3: WeakReference w = new WeakReference(hugeObject);
4: hugeObject = null;
5: GC.Collect();
6: Console.WriteLine((w.Target as WeakReferenceTest).SharkFirstName);
7. Lazy<T>
Lazy<T>提供对延迟一些大资源或资源紧张的对象的初始化的支持。在程序的生存期内,特别是在这种方式创建或执行可能不发生使用延迟初始化延迟一种或大量占用资源的对象的创建、资源的任务的执行。
1: public abstract class ThreadSafeLazyBaseSingleton<T>
2: where T : new()
3: {
4: private static readonly Lazy<T> lazy = new Lazy<T>(() => new T());
5:
6: public static T Instance
7: {
8: get
9: {
10: return lazy.Value;
11: }
12: }
13: }
8. BigInteger
BigInteger 类型 表示任意大的带符号整数。理论上来讲,该类型的数据是没有边界值限制的。该类型与其他整型类型不同,包含MinValue和MaxValue 属性。
1: string positiveString = "91389681247993671255432112000000";
2: string negativeString = "-90315837410896312071002088037140000";
3: BigInteger posBigInt = 0;
4: BigInteger negBigInt = 0;
5:
6: posBigInt = BigInteger.Parse(positiveString);
7: Console.WriteLine(posBigInt);
8: negBigInt = BigInteger.Parse(negativeString);
9: Console.WriteLine(negBigInt);
9. 未官方记录的 C# 关键字: __arglist __reftype __makeref __refvalue
第9条讲 的关键字官方文档并没有记录,可能正在测试中。然而这些关键字丰富了Visual Studio 编辑器的功能,也能被识别。
开发人员可以使用__makeref关键字创建变量。使用__refvalue修饰变量可以从 TypedReference中获得变量值。__arglist关键字与params的作用相同,可以访问参数列表。
1: int i = 21;
2: TypedReference tr = __makeref(i);
3: Type t = __reftype(tr);
4: Console.WriteLine(t.ToString());
5: int rv = __refvalue( tr,int);
6: Console.WriteLine(rv);
7: ArglistTest.DisplayNumbersOnConsole(__arglist(1, 2, 3, 5, 6));
为了使用__arglist, 需要定义ArglistTest 类
1: public static class ArglistTest
2: {
3: public static void DisplayNumbersOnConsole(__arglist)
4: {
5: ArgIterator ai = new ArgIterator(__arglist);
6: while (ai.GetRemainingCount() > 0)
7: {
8: TypedReference tr = ai.GetNextArg();
9: Console.WriteLine(TypedReference.ToObject(tr));
10: }
11: }
12: }
10. Environment.NewLine
获取为此环境定义的换行字符串。
1: Console.WriteLine("NewLine: {0} first line{0} second line{0} third line", Environment.NewLine);
11. ExceptionDispatchInfo
表示捕获特定点的异常情况。可以使用ExceptionDispatchInfo.Throw 方法,命名空间为System.Runtime.ExceptionServices。
1: ExceptionDispatchInfo possibleException = null;
2:
3: try
4: {
5: int.Parse("a");
6: }
7: catch (FormatException ex)
8: {
9: possibleException = ExceptionDispatchInfo.Capture(ex);
10: }
11:
12: if (possibleException != null)
13: {
14: possibleException.Throw();
15: }
12. Environment.FailFast()
如果想退出程序,且不需要调用任何Finally 块或Finalizers,可以使用FailFast。
1: string s = Console.ReadLine();
2: try
3: {
4: int i = int.Parse(s);
5: if (i == 42) Environment.FailFast("Special number entered");
6: }
7: finally
8: {
9: Console.WriteLine("Program complete.");
10: }
13. Debug.Assert & Debug.WriteIf & Debug.Indent
Debug.Assert——检查条件;如果条件为 false,则显示一个消息框,其中会显示调用堆栈。Debug.Assert尽在调试版中有效,在发布版中如果要执行断言,则使用Trace.Assert。
Debug.Assert(1 == 0, "The numbers are not equal! Oh my god!");
如果Assert在Debug模式下失败,则会显示下图:

14. Parallel.For & Parallel.Foreach
多线程的情况下较为常用。
Parallel.For—执行循环,迭代可以运行。
1: int[] nums = Enumerable.Range(0, 1000000).ToArray();
2: long total = 0;
3:
4: // Use type parameter to make subtotal a long, not an int
5: Parallel.For<long>(0, nums.Length, () => 0, (j, loop, subtotal) =>
6: {
7: subtotal += nums[j];
8: return subtotal;
9: },
10: (x) => Interlocked.Add(ref total, x)
11: );
12:
13: Console.WriteLine("The total is {0:N0}", total);
Interlocked.Add 方法将两个整型值相加,并将结果保存到第一个数值,可以作为原子操作。
Parallel.Foreach——执行 foreach(在 Visual Basic 中为 For Each)操作,其中在 Partitioner 上可能会并行运行迭代。

15. IsInfinity
表示数值是无穷大情况。仅double和float类型数值除以0是产生。
1: Console.WriteLine("IsInfinity(3.0 / 0) == {0}.", Double.IsInfinity(3.0 / 0) ? "true" : "false");
原文链接:http://www.codeproject.com/Articles/1021335/Top-Underutilized-Features-of-NET
Top 15 不起眼却有大作用的 .NET功能集的更多相关文章
- 不起眼却有大作用的 .NET功能集(转发)
http://www.cnblogs.com/powertoolsteam/p/top15features.html 目录 1. ObsoleteAttribute2. 设置默认值属性: Defaul ...
- The World's Top 15 Stock Exchanges by Domestic Market Capitalization
The World's Top 15 Stock Exchanges by Domestic Market Capitalization in 2008 4 Euronext Belgium, Fr ...
- Top 15 - Material Design框架和类库(译)
_Material design_是Google开发的,目的是为了统一公司的web端和手机端的产品风格.它是基于很多的原则,比如像合适的动画,响应式,以及颜色和阴影的使用.完整的指南详情请看这里(ht ...
- Top 15 Java Utility Classes
In Java, a utility class is a class that defines a set of methods that perform common functions. Thi ...
- Top 15 Tools To Make Animated GIFs From Images & Video
Creating an animated GIF picture from photos or video with Adobe Photoshop is easy, but not everyone ...
- 顺序栈的基本操作中Push压入后的- S.top = S.base + S.stacksize; 作用
#include <stdio.h> #include <malloc.h> #define TRUE 1 #define OK 1 #define ERROR 0 #defi ...
- ABAP FIELD-SYMBOLS 有大作用- 将没有可改参数的增强出口变得也能改主程序的值了
看下图代码: report z_xul_test2 中 定义了 全局变量 G_DATA1 , 分别调用了 z_xul_tes1 中的 form 和 function zbapi_test , 这两 ...
- ibatis集成Sqlite:小数据库也有大作用
作者:Vinkn 来自http://www.cnblogs.com/Vinkn/ 一.简介 Ibatis简介: Ibatis是一个类似于Hibernate的数据库ORM(对象关系映射,通俗点就是将数据 ...
- ABAP FIELD-SYMBOLS 有大作用- 将没有可改參数的增强出口变得也能改主程序的值了
看下图代码: report z_xul_test2 中 定义了 全局变量 G_DATA1 , 分别调用了 z_xul_tes1 中的 form 和 function zbapi_test , 这两 ...
随机推荐
- yformater - chrome谷歌浏览器json格式化json高亮json解析插件
yformater是一款chrome浏览器插件,用来格式化(高亮)服务端接口返回的json数据. 实际上小菜并不是第一个写这种插件的,但是现有的chrome json格式化插件实在是不太好用,索性小菜 ...
- iOS-SDWebimage底层实现原理
其实有些框架的实现原理,并没有想象中那么难,思想也很简单,主要是更新第三方框架的作者对自己写的代码,进行了多层封装,使代码的可读性降低,也就使得框架看起来比较难.我来实现以下SDWebimage的的曾 ...
- php安装的一点点事 ---wampserver
安装wampserver后,需要配置一些文件 1. 首先修改httpd.conf <Directory /> Options FollowSymLinks AllowOverride No ...
- LINQ系列:Linq to Object限制操作符
1. Where 限制操作符Where用于过滤序列,按照提供的逻辑对序列中的数据进行过滤.Where可以出现多次. 1.1 原型定义 public static IEnumerable<TSou ...
- Java 超简单实现发送邮件(可动态控制发送人数)
发送邮件的实现 需要事先引入以下几个架包,最重要的架包是jodd-3.7这个 以上架包下载地址:http://pan.baidu.com/s/1kVs7Tyv 提取密码:h22x 新建一个Util类 ...
- 前端学PHP之变量
× 目录 [1]变量定义 [2]关键字 [3]变量赋值[4]可变变量[5]变量函数 前面的话 变量是用于临时存储值的容器.这些值可以是数字.文本,或者复杂得多的排列组合.变量在任何编程语言中都居于核心 ...
- Detach Volume 操作 - 每天5分钟玩转 OpenStack(55)
上一节我们成功地通过 attach 操作为 instance 添加了 volume,而与之相对的操作是 detach,就是将 volume 从 instance 上卸载下来. 下图是 Detach 操 ...
- etlpy: 并行爬虫和数据清洗工具(开源)
etlpy是python编写的网页数据抓取和清洗工具,核心文件etl.py不超过500行,具备如下特点 爬虫和清洗逻辑基于xml定义,不需手工编写 基于python生成器,流式处理,对内存无要求 内置 ...
- Jenkins+SVN+tomcat持续集成发布
有代码更新后重新打包到tomcat再发布,是不是很烦? 看了下面的东西你就不会烦了. SVN或者git等代码版本控制工具不说了,如果是本地开发,也可以安装一个svn server端 jenkins下载 ...
- 窥探Swift之字符串(String)
之前总结过Objective-C中的字符串<Objective-C精选字符串处理方法>,学习一门新语言怎么能少的了字符串呢.Swift中的String和Objective-C语言中NSSt ...