>`
@BenAlabaster:VB支持后期绑定算术运算符.C#必须在编译时解决它们.这是语言差异.例如,VB可以将两个对象一起添加.C#不能,因为`+`没有为`object`定义.
9> dalle..:
该System.Object的类:
Equals和GetHashCode - 并非所有类都具有可比性或可散列性,应移至界面.想到IEquatable或IComparable(或类似的).
ToString - 并非所有类都可以转换为字符串,应该移动到接口.想到了IFormattable(或类似的).
该ICollection.SyncRoot属性:
促进设计不佳,外部锁几乎总是更有用.
仿制药应该从一开始就在那里:
该System.Collections中命名空间包含了很多或多或少过时的类和接口.
10> Greg Beech..:
令我恼火的事情之一就是Predicate != Func
悖论.他们都是类型的代表,T -> bool
但他们不兼容任务.
11> ChrisW..:
有些人(ISV)希望您可以在构建时将其编译为机器代码并链接它,以便创建不需要dotNet运行时的本机可执行文件.
Xenocode的Postbuild没有这样做吗?如果Visual Studio有办法做到这一点会很好......
12> tuinstoel..:
我不喜欢C#switch语句.
我想要这样的东西
switch (a) {
1 : do_something;
2 : do_something_else;
3,4 : do_something_different;
else : do_something_weird;
}
所以没有更多的休息(容易忘记)以及逗号分隔不同值的可能性.
顺便说一句,我同意OP.`switch`从根本上打破了所有语言,模仿C的deliberatly残缺版本(针对速度优化!).VB的表现要好得多,但与模式匹配(Haskell,F#...)的语言背后仍然相差很多.
一般来说,休息似乎是一个错误,是不是发出它的编译错误?它似乎只是为了缓解从C到C#的过渡(也就是教学开发者,他们不能自动通过)
13> Daniel Paull..:
我们对正确的 OO技术非常了解.解耦,合同编程,避免不正确的继承,适当使用异常,开放/封闭主体,Liskov可替代性等.还有,.Net框架没有采用最佳实践.
对我来说,.Net设计中最大的一个缺陷并不是站在巨人的肩膀上; 向使用其框架的大量程序员推广不太理想的编程范例.
如果MS关注这一点,那么软件工程世界在这十年中可以在质量,稳定性和可扩展性方面取得巨大飞跃,但唉,它似乎正在倒退.
+1为目标咆哮; 我会补充说,无法对每个类进行子类化,缺少基础类的接口,以及即使在几年后也不愿意修复框架错误
不,我说有很多情况下设计明显存在缺陷,那么当你认为它们做对了,他们仍然会弄错.例如,我在MSDN论坛上的帖子:http://social.msdn.microsoft.com/forums/en-US/wpf/thread/f677b026-0719-47d7-a0b7-a0874df2ba17/
我认为你说的是"它没有那么好",这是一个无法回答的问题.没有什么是完美的.提供细节.
14> Thomas Eyde..:
C#中的事件,您必须明确检查侦听器.不是那个事件的重点,向那些碰巧在那里的人广播?即使没有?
15> ShuggyCoUk..:
对于嵌套/递归迭代器来说,可怕的(并且对大多数人来说是非常不可见的)O(N ^ 2)行为.
我很清楚,他们知道它,知道如何解决它,但它并没有被视为有足够的优先权值得包容.
我一直在使用类似树的结构,当他们无意中以这种方式引入非常昂贵的操作时,必须更正聪明人的代码.
之美"产量的foreach"是,更简单,更语法正确的鼓励,高性能的代码,这是'成功的坑’,我想他们增加新的功能,为平台的长期成功之前,应该向往.
16> ggf31416..:
有些类实现接口,但它们没有实现该接口的许多方法,例如,Array实现IList,但9个方法中有4个抛出NotSupportedException http://msdn.microsoft.com/en-us/library/system.array_members的.aspx
17> Jay Bazuzi..:
接口中的静态成员和嵌套类型.
当接口成员具有特定于接口的类型的参数(例如, a enum
)时,这尤其有用.将enum类型嵌套在接口类型中会很不错.
18> jasonh..:
事件的非常危险的默认性质.由于订阅者被删除,您可以调用事件并处于不一致状态这一事实非常可怕.有关此主题的更多阅读,请参阅Jon Skeet和Eric Lippert的优秀文章.
19> Jon Harrop..:
null
到处.
const
无处.
API是不一致的,例如,变量数组返回void
但附加到StringBuffer
返回相同的mutable StringBuffer
.
集合接口与不可变数据结构不兼容,例如Add
,System.Collections.Generic.IList<_>
无法返回结果.
没有结构类型,所以你写System.Windows.Media.Effects.SamplingMode.Bilinear
而不是只是Bilinear
.
IEnumerator
当类应该是不可变的时,由类实现的可变接口struct
.
平等和比较是一个烂摊子:你有System.IComparable
和Equals
,但是随后你也有System.IComparable<_>
,System.IEquatable
,System.Collections.IComparer
,System.Collections.IStructuralComparable
,System.Collections.IStructuralEquatable
,System.Collections.Generic.IComparer
和System.Collections.Generic.IEqualityComparer
.
元组应该是结构,但结构不必要地抑制尾部调用消除,因此最常见和最基本的数据类型之一将不必要地分配并破坏可扩展的并行性.
20> Michael Buen..:
0兼职作为枚举
枚举的特点:http://blogs.msdn.com/abhinaba/archive/2007/01/09/more-peculiarites-of-enum.aspx
正如这个好例子所示:http:
//plus.kaist.ac.kr/~shoh/postgresql/Npgsql/apidocs/Npgsql.NpgsqlParameterCollection.Add_overload_3.html
我的建议,好好利用"@"标志:
代替:
if((myVar&MyEnumName.ColorRed)!= 0)
用这个:
if((myVar&MyEnumName.ColorRed)!= @ 0)
21> Brian Rasmus..:
要添加其他人已经提出的长点清单:
DateTime.Now == DateTime.Now
在大多数情况下,但不是所有情况.
String
这是不可变的有一堆构造和操作的选项,但StringBuilder
(这是可变的)没有.
Monitor.Enter
并且Monitor.Exit
应该是实例方法,所以不是新建一个特定的对象来锁定,你可以新建一个Monitor
并锁定它.
析构函数永远不应该被命名为析构函数.ECMA规范称它们为终结器,这对C++人群来说要少得多,但语言规范仍然将它们称为析构函数.
@Brian Rasmussen:DateTime.Now是一个非常合适的属性,因为它不是通过读取而是通过外部因素来改变.如果一个人读取SomeForm.Width之类的属性,然后 - 在用户调整表单大小后 - 再次读取它,则第二次读取的值将不同.虽然第一个DateTime.Now可能需要足够长的时间才能执行它会影响第二个读取的值,但这样的效果与执行时间相同的任何其他函数没有区别.
"DateTime.Now"一个是世界上最明显的竞争条件,但其余为+1