NET 开发者了解的15个特性

本文列举了 15 个值得了解的 C# 特性,旨在让 .NET 开发人员更好的使用 C# 语言进行开发工作。

  1. ObsoleteAttribute

    ObsoleteAttribute 适用于除组件、模块、参数和返回值以外的所有程序元素。将元素标记为 obsolete,可以通知用户该元素将在未来的版本中删除。

    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());

官方文档 - https://msdn.microsoft.com/en-us/library/system.obsoleteattribute.aspx

  1. 使用 DefaultValueAttribute 为 C# 自动实现的属性设置默认值

    DefaultValueAttribute 可以指定属性的默认值。你可以使用 DefaultValueAttribute 创建任意一个值。成员的默认值通常是其初始值。

这个属性不能用于使用特定的值自动初始化对象成员。因此,开发者必须在代码中设置初始值。

复制代码

public class DefaultValueAttributeTest

{

public DefaultValueAttributeTest()

{

// Use the DefaultValue property 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);
}

}

复制代码

自动实现的属性通过反射在类的构造函数中实现初始化。代码遍历类的所有属性,并将它们设置为默认值。

官方文档 - https://msdn.microsoft.com/zh-CN/library/system.componentmodel.defaultvalueattribute.aspx

  1. DebuggerBrowsableAttribute

    DebuggerBrowsableAttribute 用于确定是否需要以及如何实现在调试器变量窗口中显示成员变量。

复制代码

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;
}
}

}

复制代码

官方文档 - https://msdn.microsoft.com/zh-CN/library/system.diagnostics.debuggerbrowsableattribute.aspx

  1. ?? 运算符

    当左操作数非空时,?? 运算符返回左边的操作数,否则返回右边的操作数。?? 运算符定义为,将可空类型分配给非空类型时要返回的默认值。

复制代码

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");

复制代码

官方文档 - https://msdn.microsoft.com/zh-cn/library/ms173224(v=vs.80).aspx

  1. Curry 和 Partial 方法

    Curry - 在数学和计算机科学中,currying 是一种将函数的​​评估转换为多个参数(或参数元组)的技术,主要用于评估一系列函数,每个函数都有一个参数。

为了通过 C# 实现,使用扩展方法的功能。

复制代码

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 关键字进行交换。

官方文档 - https://en.wikipedia.org/wiki/Currying#/Contrast_with_partial_function_application

Partial - 在计算机科学中,Partial 应用程序(或 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));

官方文档 - https://en.wikipedia.org/wiki/Partial_application

  1. WeakReference

    弱引用使得在收集器收集对象时,仍允许应用程序访问该对象。如果你需要这个对象,你仍然可以获得一个强有力的引用,并阻止它被收集。

复制代码

WeakReferenceTest hugeObject = new WeakReferenceTest();

hugeObject.SharkFirstName = "Sharky";

WeakReference w = new WeakReference(hugeObject);

hugeObject = null;

GC.Collect();

Console.WriteLine((w.Target as WeakReferenceTest).SharkFirstName);

复制代码

如果垃圾收集器没有明确被地调用,那么仍有很大的可能性弱引用会被分配。

官方文档 - https://msdn.microsoft.com/en-us/library/system.weakreference.aspx

  1. Lazy

    使用延迟初始化,可推迟创建大型资源密集型对象或执行资源密集型任务时,在程序生命周期内创建或执行指定类的发生。

复制代码

public abstract class ThreadSafeLazyBaseSingleton

where T : new()

{

private static readonly Lazy lazy = new Lazy(() => new T());

public static T Instance
{
get
{
return lazy.Value;
}
}

}

复制代码

官方文档 - https://msdn.microsoft.com/en-us/library/dd642331(v=vs.110).aspx

  1. BigInteger

    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);

复制代码

官方文档 - https://msdn.microsoft.com/en-us/library/system.numerics.biginteger(v=vs.110).aspx

9.没有官方文档的C#关键字 (__arglist / __reftype / __makeref / __refvalue)

一些 C# 关键字是没有官方文档的,没有文档的原因可能是这些关键字没有经过充分测试。但是,这些关键字已被 Visual Studio 编辑器着色并被识别为官方关键字。

你可以使用 __makeref 关键字在变量中创建一个类型化的引用,使用 __reftype 关键字提取由类型化引用表示的变量的原始类型,从 TypedReference 中使用 __refvalue 关键字获取参数值,使用 __arglist 访问参数列表。

复制代码

int i = 21;

TypedReference tr = __makeref(i);

Type t = __reftype(tr);

Console.WriteLine(t.ToString());

int rv = __refvalue( tr,int);

Console.WriteLine(rv);

ArglistTest.DisplayNumbersOnConsole(__arglist(1, 2, 3, 5, 6));

复制代码

在使用 __arglist 时,需要 ArglistTest 类。

复制代码

public static class ArglistTest

{

public static void DisplayNumbersOnConsole(__arglist)

{

ArgIterator ai = new ArgIterator(__arglist);

while (ai.GetRemainingCount() > 0)

{

TypedReference tr = ai.GetNextArg();

Console.WriteLine(TypedReference.ToObject(tr));

}

}

}

复制代码

参考 - http://www.nullskull.com/articles/20030114.asp和http://community.bartdesmet.net/blogs/bart/archive/2006/09/28/4473.aspx

  1. Environment.NewLine

    获取当前环境下的换行字符串。

Console.WriteLine("NewLine: {0} first line{0} second line{0} third line", Environment.NewLine);

官方文档 - https://msdn.microsoft.com/en-us/library/system.environment.newline(v=vs.110).aspx

  1. ExceptionDispatchInfo

    保留代码中的某个被捕获的异常。你可以使用 ExceptionDispatchInfo.Throw 方法,这个方法在 System.Runtime.ExceptionServices namespace 中。这个方法可用于引发异常并保留原始堆栈的调用过程。

复制代码

ExceptionDispatchInfo possibleException = null;

try

{

int.Parse("a");

}

catch (FormatException ex)

{

possibleException = ExceptionDispatchInfo.Capture(ex);

}

if (possibleException != null)

{

possibleException.Throw();

}

复制代码

被捕获的异常可以在另一个方法或另一个线程中再次抛出。

官方文档 - https://msdn.microsoft.com/en-us/library/system.runtime.exceptionservices.exceptiondispatchinfo(v=vs.110).aspx

  1. Environment.FailFast()

    如果你想在不调用任何 finally 块或终结器的情况下退出程序,可以使用 FailFast。

复制代码

string s = Console.ReadLine();

try

{

int i = int.Parse(s);

if (i == 42) Environment.FailFast("Special number entered");

}

finally

{

Console.WriteLine("Program complete.");

}

复制代码

如果 i 等于 42,该 finally 块将不会被执行。

官方文档 - https://msdn.microsoft.com/zh-cn/library/ms131100(v=vs.110).aspx

  1. Debug.Assert&Debug.WriteIf&Debug.Indent

    Debug.Assert 用于检查条件,如果条件是 false,则输出消息并显示一个显示调用堆栈的消息框。

Debug.Assert(1 == 0, "The numbers are not equal! Oh my god!");

如果断言在调试模式下失败,则显示下面的警报,其中包含指定的消息。

Debug.WriteIf - 如果判断的结果是 true,则会将有关调试的信息写入 Listeners 收集中的跟踪侦听器内。

Debug.WriteLineIf(1 == 1, "This message is going to be displayed in the Debug output! =)");

Debug.Indent/Debug.Unindent – 使得 IndentLevel 逐一递增。

复制代码

Debug.WriteLine("What are ingredients to bake a cake?");

Debug.Indent();

Debug.WriteLine("1. 1 cup (2 sticks) butter, at room temperature.");

Debug.WriteLine("2 cups sugar");

Debug.WriteLine("3 cups sifted self-rising flour");

Debug.WriteLine("4 eggs");

Debug.WriteLine("1 cup milk");

Debug.WriteLine("1 teaspoon pure vanilla extract");

Debug.Unindent();

Debug.WriteLine("End of list");

复制代码

如果想在调试输出窗口中显示 cake 的成分,可以使用上面的代码。

官方文档:Debug.Assert,Debug.WriteIf,Debug.Indent / Debug.Unindent

  1. Parallel.For&Parallel.Foreach

    Parallel.For - 执行一个可并行运行迭代的 for 循环。

复制代码

int[] nums = Enumerable.Range(0, 1000000).ToArray();

long total = 0;

// Use type parameter to make subtotal a long, not an int

Parallel.For(0, nums.Length, () => 0, (j, loop, subtotal) =>

{

subtotal += nums[j];

return subtotal;

},

(x) => Interlocked.Add(ref total, x)

);

Console.WriteLine("The total is {0:N0}", total);

复制代码

Interlocked.Add 方法添加两个整数,并用总和替换第一个整数。

Parallel.Foreach - 执行可并行运行迭代的 foreach 操作。

复制代码

int[] nums = Enumerable.Range(0, 1000000).ToArray();

long total = 0;

Parallel.ForEach<int, long>(nums, // source collection

() => 0, // method to initialize the local variable

(j, loop, subtotal) => // method invoked by the loop on each iteration

{

subtotal += j; //modify local variable

return subtotal; // value to be passed to next iteration

},

// Method to be executed when each partition has completed.

// finalResult is the final value of subtotal for a particular partition.

(finalResult) => Interlocked.Add(ref total, finalResult));

Console.WriteLine("The total from Parallel.ForEach is {0:N0}", total);

复制代码

官方文档:Parallel.For 和 Parallel.Foreach

  1. IsInfinity

    返回一个值,用于表示某一个数是否为负无穷或正无穷大。

Console.WriteLine("IsInfinity(3.0 / 0) == {0}.", Double.IsInfinity(3.0 / 0) ? "true" : "false");

官方文档 - https://msdn.microsoft.com/en-us/library/system.double.isinfinity(v=vs.110).aspx

原文链接:https://www.codeproject.com/Articles/1021335/Top-Underutilized-Features-of-NET

转载请注明出自:葡萄城控件

相关阅读:

是什么优化让 .NET Core 性能飙升?

C#开发人员应该知道的13件事情

是什么让C#成为最值得学习的编程语言

开发者了解NET的15个特性的更多相关文章

  1. Java SE 15 新增特性

    Java SE 15 新增特性 作者:Grey 原文地址:Java SE 15 新增特性 源码 源仓库: Github:java_new_features 镜像仓库: GitCode:java_new ...

  2. Java 15 新特性:文本块

    大家好,我是DD,今天继续来学点Java的新特性! 假设有这样一个场景,我们需要做一个工具.用来自动生成项目文档,文档可以通过浏览器查看,所以最后产出物肯定是一堆html文件.为了让这些html文件更 ...

  3. Java 15 新特性:隐藏类

    什么是隐藏类 隐藏类,是一种不能被其他类直接使用的类.引入隐藏类的主要目的是给框架来使用,使得框架可以在运行时生成类,并通过反射间接使用它们.可能有点抽象,不要紧,下面我们通过一个例子来直观的认识它! ...

  4. 值得 .NET 开发者了解的15个特性

    本文列举了 15 个值得了解的 C# 特性,旨在让 .NET 开发人员更好的使用 C# 语言进行开发工作. 1. ObsoleteAttribute ObsoleteAttribute 适用于除组件. ...

  5. Web开发者不可不知的15条编码原则

    HTML已经走过了近20的发展历程.从HTML4到XHTML,再到最近十分火热的HTML5,它几乎见证了整个互联网的发展.但是,即便到现在,有很多基础的概念和原则依然需要开发者高度注意.下面,向大家介 ...

  6. Guava 15新特性介绍

    原文:http://www.javacodegeeks.com/2013/10/guava-15-new-features.html Guava 是众所周知的google出品的开源工具包,十分好用,本 ...

  7. 从开发者角度解析 Android N 新特性!

    大清早看到 Google 官方博客发布 Android N 的开发者预览版,立马从床上跳起来开始仔仔细细的读起来. 从开发者角度来看,Android N 的更新并不算大.网上之前流传的一些 Andro ...

  8. Web 开发者不可不知的15条编码原则

    HTML 已经走过了近20的发展历程.从HTML4到XHTML,再到最近十分火热的HTML5,它几乎见证了整个互联网的发展.但是,即便到现在,有很多基础的概念和原则依然需要开发者高度注意.下面,向大家 ...

  9. Web 设计与开发者必须知道的 15 个站点

    新闻来源:catswhocode.com公司博客整整一个月没有更新了,最近一段时间,全公司都忙于两件事,为海尔集团做定制,为一个合作伙伴做 OEM,终于有了眉目.工作期间,常用到一些工具与帮助站点,今 ...

随机推荐

  1. hdoj--2534--Score(gcd)

    Score Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Subm ...

  2. ubuntu 使用阿里云 apt 源

    以下内容来自 https://opsx.alibaba.com/mirror Ubuntu对应的“帮助”信息 修改方式:打开 /et/apt/sources.list 将http://archive. ...

  3. ROS-package.xml文件标签解读

    前言:package.xml是一个XML文件名为package.xml中必须包括与任何兼容包的根文件夹.此文件定义有关包的属性,例如包名称,版本号,作者,维护者以及其他catkin包的依赖关系. 标签 ...

  4. Habernate配置一对一,一对多,多对多(二)

    一.开篇 紧接着上篇的博客来写:http://www.cnblogs.com/WJ--NET/p/7845000.html(habernate环境的搭建) 二.配置一对一 2.1.新建客户类和公司类( ...

  5. AutoFac与ASP.NET MVC结合使用

    MVC下的配置 通过NuGet安装AutoFac插件:Install-Package Autofac.Mvc5 在Global中调用: var builder= new ContainerBuilde ...

  6. UWP 开发APP准备工作

    每新建一个UWP之后,都要进行一番相同的处理步骤,才能使Mobile的使用体验更好,故总结如下: 1.订阅Mobile后退导航事件 在App.xaml.cs文件中OnLaunched方法中添加 Sys ...

  7. Hibernate框架学习(九)——Criteria语法

    一.语法 1.基本查询 2.条件查询 3.分页查询 4.排序查询 5.统计查询 二.离线查询 1.非离线的Criteria 2.离线的Criteria 3.演示 public class Demo2 ...

  8. What is the difference between arguments and parameters?

    What is the difference between arguments and parameters? Parameters are defined by the names that ap ...

  9. Ubuntu 16.04安装Caffe的记录及FCN官方代码的配置

    相关内容搜集自官方文档与网络,既无创新性,也不求甚解,我也不了解Caffe,仅仅搭上之后做个记录,方便以后重装 安装依赖项sudo apt-get install libprotobuf-dev li ...

  10. runloop的source

    以上是完整的 CFRunLoop 和 CFRunLoopMode 的结构体源码(太长了我的妈,用不着看完),下面我精简一下,把重要的留下,看如下代码(可以仔细看一下,加深印象): 上面是精简出来比较关 ...