本文列举了 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
2. 使用 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
3. 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
4. ?? 运算符
当左操作数非空时,?? 运算符返回左边的操作数,否则返回右边的操作数。?? 运算符定义为,将可空类型分配给非空类型时要返回的默认值。
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
5. 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
6. 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
7. Lazy<T>
使用延迟初始化,可推迟创建大型资源密集型对象或执行资源密集型任务时,在程序生命周期内创建或执行指定类的发生。
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; } } }
官方文档 - https://msdn.microsoft.com/en-us/library/dd642331(v=vs.110).aspx
8. 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
10. 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
11. 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(); }
被捕获的异常可以在另一个方法或另一个线程中再次抛出。
12. 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
13. 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
14. 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<long>(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
15. 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
转载请注明出自:葡萄城控件
C#开发工具推荐
ComponentOne Studio Enterprise 是一款专注于企业应用的.NET全功能控件套包,支持 WinForms、WPF、UWP、ASP.NET MVC 等多个平台,帮助在缩减成本的同时,提前交付丰富的桌面、Web 和移动企业应用。控件支持的范围广泛,包含了表格和数据管理、图表和数据可视化、流行的 UI 界面等,为企业应用开发提供高性能的控件工具。
本文转载自:http://powertoolsteam.iteye.com/blog/2414090
相关推荐
.NET 4.5工具箱是这个平台的一个重要组成部分,它集成了针对.NET Framework 4.5的开发和编译功能,同时也兼容3.5和4.0版本的开发环境,为开发者带来了极大的便利。 首先,我们来了解一下.NET Framework 4.5。这是...
VB.NET与C#比较是一个对比两种.NET编程语言特性和语法差异的资源网站,对于那些在选择编程语言时犹豫不决的.NET开发者而言,这里的信息可以帮助他们做出更明智的决策。 综上所述,这些网站覆盖了.NET技术的各个方面...
这使得.NET开发者可以利用Drools的强大规则引擎,而无需学习Java或在两个平台上切换。 **关键组件** - **drools-dotnet.dll**:这是Drools.NET的主要库,包含了.NET平台上的核心规则引擎实现。 - **drools-3.0.dll...
TextAnalysisTool.NET便是这样一款专为.NET开发者设计的日志查看和调试工具。它的出现,使得在海量的日志数据中寻找关键信息变得更加便捷。 首先,我们要明确.TextAnalysisTool.NET的核心功能——日志分析。日志...
总的来说,.NET Reflector 6.6.0.30是.NET开发者的强大辅助工具,它通过提供深入的代码洞察力,帮助提升开发效率,解决复杂问题,并增进对.NET技术的理解。使用这个版本的用户可以通过反编译代码来学习新的编程技巧...
本系列课程聚焦于.NET Framework 2.0中的新特性和改进,旨在帮助开发者更好地理解和利用这些新功能,提升开发效率和软件性能。下面我们将深入探讨.NET Framework 2.0的一些关键更新和特性。 1. **泛型(Generics)*...
最后,考虑到.NET开发者在选择工具时的多样性,"动软.net代码生成器"为这一群体提供了一个值得信赖的选项。它的易用性、高效率和不断创新的特点,使其成为.NET开发领域中一个不可多得的开发辅助工具。在不断变化的...
《Eziriz .NET Reactor 5.9.2.0:强大的.NET代码保护与授权解决方案》 Eziriz .NET Reactor是一款专为.NET开发者设计的强大工具,其5.9....对于任何希望保护自己辛勤工作的.NET开发者而言,这都是一个值得信赖的选择。
学习这两个项目,你可以深入了解ASP.NET MVC框架的工作原理,理解如何在实际项目中应用这些技术。你可以分析代码结构,查看控制器是如何处理请求,模型是如何与数据库交互,以及视图是如何渲染数据的。同时,这也是...
NanUI是一个面向.NET开发者,特别是.NET和.NET Core开发者的开源项目,它的主要目标是为桌面应用程序提供一个现代化的用户界面解决方案。通过NanUI,开发者可以利用HTML5、CSS3以及JavaScript等Web前端技术来设计和...
LumiSoft.Net是一个开源的组件库,专门为.NET开发者设计,提供了丰富的网络应用程序功能。这个库以其易用性和高效性著称,尤其在邮件发送与接收(包括邮件解析)方面表现优秀,同时也支持其他多种网络功能。 邮件...
"FCKeditor.NET版"是一个专门为.NET开发者设计的网页编辑器解决方案,它结合了FCKeditor的强大功能和.NET框架的便利性。FCKeditor是一款开源的、基于JavaScript的富文本编辑器,广泛用于创建网页内容的可视化编辑...
对于.NET开发者来说,ILSpy是一个不可或缺的工具。它可以用来学习和理解第三方库的内部实现,从而提高开发效率。在遇到无法访问源代码的问题时,ILSpy可以帮助开发者找到解决方案。同时,它也是进行逆向工程和安全...
".NET 4.0项目自动生成软件"利用先进的自动化技术,仅需五秒钟,即可根据预设的模板生成一个完整的项目结构。这包括了必要的文件、目录结构、代码模板以及配置文件等,极大地减少了开发者手动创建这些基础元素的时间...
8. **网络编程**:由于.NET Framework提供了丰富的网络编程API,Delphi.NET开发者可以轻松创建网络应用程序,实现HTTP、FTP、SMTP等协议的功能。 9. **图形和多媒体**:Delphi.NET可以利用GDI+或DirectX等图形库,...
**Lucene.net学习帮助文档** Lucene.net是一个开源全文搜索引擎库,它是Apache Lucene项目的一部分,专门针对.NET ...无论你是.NET开发者还是对全文检索技术感兴趣,Lucene.net都是一个值得投入时间和精力去掌握的库。
IKVM.NET v8.1 是一个独特的开源项目,它允许.NET开发者在C#或任何其他.NET语言中直接利用Java库,包括.jar文件。这个工具由Glenn Block开发,旨在为.NET Framework提供Java虚拟机(JVM)的功能。通过IKVM.NET,...
.NET ORM框架,全称为Object-Relational Mapping(对象关系映射)框架,是.NET开发者用于简化数据库操作的重要工具。ORM框架允许程序员使用面向对象的方式来处理数据库,将数据库中的数据与程序中的对象进行关联,...
Npgsql是.NET开发者在处理PostgreSQL数据库时的一个关键工具,它是专门为.NET Framework 3.5设计的版本2.0.4。这个开发包提供了一种高效、强大的方式来与PostgreSQL数据库进行交互,相比传统的ODBC接口,Npgsql提供...
Browser.Net项目就是这样一个专门为.NET开发者提供的、基于IE内核的Web浏览器组件,它允许程序员使用C#语言来构建和控制具有IE渲染能力的应用程序。 Browser.Net的核心功能包括: 1. **网页渲染**:该库提供了与IE...