在我从this question了解到以下内容后,我想到了这一点:
where T : struct
我们C#开发人员都知道C#的基础知识 . 我的意思是声明,条件,循环,运算符等 .
我们中的一些人甚至掌握了Generics,anonymous types,lambdas,LINQ等东西......
但是,即使C#粉丝,瘾君子,专家几乎不知道C#最隐藏的功能或技巧是什么?
到目前为止,这是显示的功能:
关键词
-
var
by Michael Stum
189using()
陈述kokos -
readonly
by kokos -
as
by Mike Stone -
as
/is
by Ed Swangren -
as
/is
(改进)Rocketpants -
default
by deathofrats -
global::
by pzycoman -
using()
块AlexCuse -
volatile
by Jakub Šturc -
extern alias
by Jakub Šturc
属性
语法
18944 ??(coalesce nulls)运算符kokos
-
数字标记Nick Berardi
-
where T:new
by Lars Mæhlum -
Keith的隐式泛型
-
单参数lambdas by Keith
-
Keith的自动属性
-
Keith的命名空间别名
-
@variablenames by marxidad
-
event
运营商marxidad -
格式字符串括号Portman
-
属性访问器可访问性修饰符xanadont
-
JasonS的条件(三元)运算符(
?:
)
189checked
和unchecked
运营商Binoj Antony -
implicit and explicit
运营商Flory
语言功能
-
Nullable类型Brad Barker
-
Keith的匿名类型
-
__makeref __reftype __refvalue
by Judah Himango -
对象初始化程序lomaxx
-
David in Dakota格式化字符串
-
扩展方法marxidad
-
partial
方法Jon Erickson -
预处理程序指令John Asbeck
-
DEBUG
预处理器指令Robert Durgin -
运算符重载SefBkn
-
由chakrit键入推理
-
布尔运算符taken to next level by Rob Gough
-
将值类型变量作为接口传递给Roman Boiko
-
通过Roman Boiko以编程方式确定声明的变量类型
-
静态构造函数Chris
-
使用LINQ roosteronacid轻松实现眼睛/浓缩ORM映射
-
__arglist
by Zac Bowling
Visual Studio功能
-
在Himadri中选择编辑器中的文本块
-
片段由DannySmurf
框架
-
TransactionScope
by KiwiBastard -
DependantTransaction
by KiwiBastard -
Nullable<T>
by IainMH -
Mutex
by Diago -
System.IO.Path
by ageektrapped -
WeakReference
by Juan Manuel
方法和属性
-
String.IsNullOrEmpty()
方法KiwiBastard -
List.ForEach()
方法KiwiBastard -
BeginInvoke()
,EndInvoke()
方法Will Dean
189Nullable<T>.HasValue
和Nullable<T>.Value
属性Rismo -
GetValueOrDefault
方法John Sheehan
提示与技巧
-
事件处理程序的好方法Andreas H.R. Nilsson
-
John的大写比较
-
通过dp访问没有反射的匿名类型
-
通过Will懒惰地实例化集合属性的快捷方法
-
类似JavaScript的匿名内联函数roosteronacid
其他
-
netmodules by kokos
30 回答
这个不是“隐藏”的,因为它被误解了 .
很多注意力都集中在算法“map”,“reduce”和“filter”上 . 大多数人没有意识到的是.NET 3.5添加了所有这三种算法,但基于它们是LINQ的一部分,它给了它们非常的SQL-ish名称 .
使用LINQ对过去采用迭代和条件的集合进行内联工作的能力非常有 Value . 值得了解所有LINQ扩展方法如何帮助您的代码更加紧凑和可维护 .
对于真正使用
System.IO.Path.Combine()
的人来说,这并不是他们应该做到的 . 实际上,整个Path类非常有用,但 no one uses it!我愿意打赌每个 生产环境 应用程序都有以下代码,即使它不应该:
用于系统独立的换行符 .
我倾向于发现大多数C#开发人员都不知道'可空'类型 . 基本上,可以具有空值的基元 .
将可空双精度数num1设置为null,然后将常规双精度数num2设置为num1或-100(如果num1为空) .
http://msdn.microsoft.com/en-us/library/1t3y8s4s(VS.80).aspx
关于Nullable类型还有一件事:
它返回String.Empty . 有关详细信息,请查看this链接
混入 . 基本上,如果要向多个类添加一个功能,但不能为所有类使用一个基类,请让每个类实现一个接口(没有成员) . 然后,写一个扩展方法 for the interface ,即
当然,牺牲一些清晰度 . 但它的确有效!
如果要在不调用任何finally块或终结器的情况下退出程序,请使用FailFast:
使用@作为关键字的变量名 .
我最喜欢的技巧是使用null coalesce operator和括号为我自动实例化集合 .
Unions (the C++ shared memory kind) in pure, safe C#
如果不采用不安全的模式和指针,您可以让类成员在类/结构中共享内存空间 . 鉴于以下课程:
您可以通过操作Int32字段来修改字节字段的值,反之亦然 . 例如,这个程序:
输出:
只需使用System.Runtime.InteropServices添加;
从方法返回匿名类型并访问成员而不进行反射 .
Avoid checking for null event handlers
在声明时向事件添加一个空委托,禁止在调用它之前总是检查该事件是否真棒 . 例:
让你这样做
而不是这个
另请参阅Eric Lippert关于此主题的related discussion和blog post(以及可能存在的缺点) .
来自Rick Strahl:
你可以链?运算符,以便您可以进行一堆空比较 .
该泛型类型中的'default'关键字:
如果T是引用类型,则返回'null';如果是int,则返回0;如果是布尔值,则返回false,等等 .
以下是一些有趣的隐藏C#功能,以未记录的C#关键字的形式:
这些是未记录的C#关键字(甚至Visual Studio识别它们!),这些关键字是为了在泛型之前更有效的装箱/拆箱而添加的 . 它们与System.TypedReference结构协同工作 .
还有__arglist,用于可变长度参数列表 .
人们不太了解的一件事是System.WeakReference - 一个非常有用的类,它跟踪一个对象,但仍然允许垃圾收集器收集它 .
最有用的"hidden"功能是yield return关键字 . 它知道了吗 . LINQ Build 于此之上;它允许通过在引擎盖下生成状态机来执行延迟执行的查询 . Raymond Chen最近发布了关于internal, gritty details的文章 .
这是正则表达式和文件路径的一个有用的:
@告诉编译器忽略字符串中的任何转义字符 .
我认为C#(.NET 3.5)中最不受欢迎和鲜为人知的功能之一是Expression Trees, especially 与Generics和Lambdas结合使用时 . 这是一种API创建方法,像NInject和Moq这样的新库正在使用 .
例如,假设我想要使用API注册方法,并且API需要获取方法名称
鉴于此课程:
之前,通常看到开发人员使用字符串和类型(或其他主要基于字符串的方式)执行此操作:
嗯,由于缺乏强力打字,这很糟糕 . 如果我重命名“SomeMethod”怎么办?现在,在3.5中,我可以以强类型的方式执行此操作:
其中RegisterMethod类使用
Expression<Action<T>>
,如下所示:这是我现在爱上Lambdas和Expression Trees的一个重要原因 .
?? - 合并运算符
using(statement / directive) - 非常好的关键字,不仅可以用于调用Dispose
readonly - 应该多用
netmodules - 太糟糕了,Visual Studio中没有支持
我记得有一次我的同事在比较之前总是将字符串换成大写字母 . 我一直想知道为什么他这样做,因为我觉得首先转换为小写是更“自然” . 现在读完这本书后,我知道为什么 .
属性一般,但最重要的是DebuggerDisplay . 为您节省数年 .
我喜欢的两件事是自动属性,因此您可以进一步折叠代码:
变
对象初始值设定项:
变
@Ed,我对发布这个有点保持沉默,因为它只不过是挑剔 . 但是,我会在您的代码示例中指出:
如果您打算使用'is',为什么要使用'as'进行安全投射?如果你确定obj确实是MyClass,那么沼泽标准的演员:
......永远不会失败 .
同样,你可以说:
我不太了解.NET的内部结构,但我的直觉告诉我,这会将最多两次类型转换操作减少到最多一次 . 无论如何,它几乎不可能破坏处理银行;就个人而言,我认为后一种形式看起来也更清洁 .
如果您尝试在String.Format表达式中使用大括号...
lambdas and type inferrence 被低估了 . Lambdas can have multiple statements 和他们 double as a compatible delegate object 自动(只是确保签名匹配),如:
请注意,我没有
new CancellationEventHandler
,也不必指定sender
和e
的类型,它们可以从事件中输入 . 这就是为什么编写整个delegate (blah blah)
并不需要您指定参数类型的麻烦 .Lambdas don't need to return anything 和类型推断在这样的上下文中非常强大 .
顺便说一句,你总是可以在函数式编程意义上返回 Lambdas that make Lambdas . 例如,这是一个lambda,它使lambda处理Button.Click事件:
请注意链接:
(dx, dy) => (sender, e) =>
这就是为什么我很高兴参加函数式编程课程:-)
除了C中的指针,我认为这是你应该学习的另一个基本的东西:-)
别名仿制药:
它允许您使用
ASimpleName
,而不是Dictionary<string, Dictionary<string, List<string>>>
.当你在很多地方使用相同的通用大而复杂的东西时使用它 .
只是想澄清一下......它并没有告诉它忽略转义字符,它实际上告诉编译器将字符串解释为文字 .
如果你有
它实际上会打印出来(注意它甚至包括用于缩进的空格):
其他一切,加上
1)隐式泛型(为什么只有方法而不是类?)
2)带有一个参数的简单lambda:
3)匿名类型和初始化者:
另一个:
4)自动属性可以有不同的范围:
谢谢@pzycoman提醒我:
5)命名空间别名(不是你可能需要这个特殊的区别):
我会想到“yield” . 像[DefaultValue()]这样的一些属性也是我的最爱 .
“var”关键字更为人所知,但您也可以在.NET 2.0应用程序中使用它(只要您将其设置为输出2.0代码),这似乎并不是很清楚 .
编辑:kokos,谢谢指出??运营商,'s indeed really useful. Since it'有点难以谷歌(因为??只是被忽略),这是该运营商的MSDN文档页面:?? Operator (C# Reference)
真,假,FileNotFound?
也许不是一种先进的技术,但我总是看到让我疯狂的一种技术:
可以浓缩为:
很长一段时间我都不知道“as”关键字 .
VS
如果obj不是MyClass,则第二个将返回null,而不是抛出类强制转换异常 .