目录

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功能集的更多相关文章

  1. 不起眼却有大作用的 .NET功能集(转发)

    http://www.cnblogs.com/powertoolsteam/p/top15features.html 目录 1. ObsoleteAttribute2. 设置默认值属性: Defaul ...

  2. 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 ...

  3. Top 15 - Material Design框架和类库(译)

    _Material design_是Google开发的,目的是为了统一公司的web端和手机端的产品风格.它是基于很多的原则,比如像合适的动画,响应式,以及颜色和阴影的使用.完整的指南详情请看这里(ht ...

  4. Top 15 Java Utility Classes

    In Java, a utility class is a class that defines a set of methods that perform common functions. Thi ...

  5. 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 ...

  6. 顺序栈的基本操作中Push压入后的- S.top = S.base + S.stacksize; 作用

    #include <stdio.h> #include <malloc.h> #define TRUE 1 #define OK 1 #define ERROR 0 #defi ...

  7. ABAP FIELD-SYMBOLS 有大作用- 将没有可改参数的增强出口变得也能改主程序的值了

    看下图代码: report  z_xul_test2 中 定义了 全局变量 G_DATA1 , 分别调用了 z_xul_tes1 中的 form  和 function zbapi_test , 这两 ...

  8. ibatis集成Sqlite:小数据库也有大作用

    作者:Vinkn 来自http://www.cnblogs.com/Vinkn/ 一.简介 Ibatis简介: Ibatis是一个类似于Hibernate的数据库ORM(对象关系映射,通俗点就是将数据 ...

  9. ABAP FIELD-SYMBOLS 有大作用- 将没有可改參数的增强出口变得也能改主程序的值了

    看下图代码: report  z_xul_test2 中 定义了 全局变量 G_DATA1 , 分别调用了 z_xul_tes1 中的 form  和 function zbapi_test , 这两 ...

随机推荐

  1. Go语言实战 - 创业进行时之创业伊始

    在工作了10年之后,我于32岁的年纪在两个月前辞职创业了. 简单介绍一下之前的整个职业生涯,挺典型的,工程师 –> 资深工程师 –> 架构师 –> 项目经理 –> 部门经理,可 ...

  2. [ASP.NET MVC 小牛之路]10 - Controller 和 Action (2)

    继上一篇文章之后,本文将介绍 Controller 和 Action 的一些较高级特性,包括 Controller Factory.Action Invoker 和异步 Controller 等内容. ...

  3. 《Entity Framework 6 Recipes》中文翻译系列 (45) ------ 第八章 POCO之获取原始对象与手工同步对象图和变化跟踪器

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 8-6  获取原始对象 问题 你正在使用POCO,想从数据库获取原始对象. 解决方案 ...

  4. How to use the function of assembly.

    Here are some simple conceptions that I summarized: 1, %rsp    -----  top of the stack 2, %rbp    -- ...

  5. for 循环打印图形

    public class For { public static void main(String[] args) { //"使用双层for循环打印图形时,外层管行,内层管列",那 ...

  6. JVM字节码指令

    invokevirtual 调用实例方法 invokespecial 调用父类构造,实例初始化方法,私有方法 dup 复制栈顶数值,并且复制值进栈,pop/pop2为栈顶值出栈 aload_0 加载第 ...

  7. python3.5 正则表达式

    我们平时上网的时候,经常需要在一些网站上注册帐号,而注册帐号的时候对帐号名称会有一些要求. 比如: 上面的图片中,输入的邮件地址.密码.手机号 才可以注册成功. 我们需要匹配用户输入的内容,判断用户输 ...

  8. 打造自己的html5视频播放器

    前段时间重新学习了一下html5的video部分,以前只是停留在标签的使用上,这一次决定深入了解相关的API,并运用这些API打造一个简单的视频播放器.所谓“打造自己的”,就是要自己重写video标签 ...

  9. 控制对话框风格的activity的显示大小与位置

    项目开发的需要,因为到现在项目接近完工,用户提出对条件筛选方式进行修改,为做到最小的改动实现用户的需求,各种百度,对于对话框风格大家普遍使用PopupWindow,但由于之前开发设计时使用的是acti ...

  10. Mac OSX网络诊断命令

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 下面是一些Mac OSX下常用的网络诊断命令.它们能帮助我们发现网络问题.文中提到 ...