任何产品或框架都会发展。主要是为了满足用户需求,利用新的计算能力并使其变得更好而做的。有时,主要设计目标也会随产品而改变。C#或.net框架也不例外。我们看到,今天的第四版与第一版相比有很大不同。但是事情成为阻碍这种向后兼容的障碍。
在大多数框架/产品中,如果不需要支持向后兼容性,则某些功能将被切断。据您介绍,C#/。net中的这些功能是什么?
请为每个答案提及一项功能。
任何产品或框架都会发展。主要是为了满足用户需求,利用新的计算能力并使其变得更好而做的。有时,主要设计目标也会随产品而改变。C#或.net框架也不例外。我们看到,今天的第四版与第一版相比有很大不同。但是事情成为阻碍这种向后兼容的障碍。
在大多数框架/产品中,如果不需要支持向后兼容性,则某些功能将被切断。据您介绍,C#/。net中的这些功能是什么?
请为每个答案提及一项功能。
Answers:
我会摆脱非通用集合。他们真是可恶...在很多情况下,我在使用linq,不得不做类似的事情
var customObjects = container.CustomObjects.Cast<CustomObject>();
每次我必须这样做时,我的灵魂就会死掉一小部分。
作为类型无效。为什么在地球上是“无效”类型?它没有实例,没有值,您不能将其用作泛型类型参数,形式参数类型,局部类型,字段类型或属性类型。它没有任何意义。实际上,这是关于方法调用对虚拟机堆栈有什么影响的事实。但是虚拟机就是这样:虚拟机。实际的机器会将返回的值放在寄存器中(通常是x86上的EAX),根本不影响堆栈!虚空作为一种类型只是个坏主意。
更糟糕:在指针类型中使用时void*
,意味着完全不同使用时,与在返回类型中使用时的。现在,它的意思是“指向未知类型的存储位置的指针”,这与“不返回任何值的方法”的含义没有任何关系。
我们可以将替换void*
为指针类型IntPtr
。(和void**
与IntPtr*
等)。我们可以更换空与“单位”,有一个值,即空类型返回类型。然后,CLR的实现可以确定一个单元类型的函数调用可以适当地优化其对寄存器或堆栈的使用,因为知道可以安全地忽略“返回”的null。
在这样的世界里,你不再需要分开Func<A, R>
和Action<T>
代表。Action<T>
就是Func<T, Unit>
。
Task
只是一个Task<Unit>
。重新实现异步CTP的库位让我真的很想...
空语句;
。容易出错,几乎总是输入错误,并且没有给您带来尚未表达的附加含义{}
。
引用类型数组的不安全协方差。启用类型安全协方差后IEnumerable<T>
,至少对数组协方差的某些需求已消失。(如果我们有一个协变的只读列表接口,那么我们根本就不需要它。)
IList<T>
从继承而来的,IReadableList<out T>
并且是非泛型的IPemutable
,它可以支持排序之类的事情,但是数组更容易支持它。
一元加运算符。一直以来都是最有用的运算符。如果我们不必为了向后兼容而保留它,我会心跳加速。谁用这个东西,有人吗?
(澄清:一元加运算符+x
不是预增运算符++x
,不是后增运算符x++
,也不是二进制加法运算符x+y
。)
+1 == 1
。几乎没有操作,这真是太糟糕了。
if(a == +1 || a == -1){...}
。
将数字文字默认为 double
对于大多数商务应用程序而言,decimal
还是更合适……或者最好是删除默认值的概念,然后强迫开发人员真正做出选择。
(“删除默认值”也适用于其他一些情况。例如,我已经放弃说服所有人默认应该密封类,但是我认为说服人们应该考虑的内容更容易是否应该密封其新类,并使其明确。)
方法和类型的Array
和List<T>
,成为过时的LINQ的,例如:
Array.TrueForAll
可以替换为 Enumerable.All
Array.FindAll
可以替换为 Enumerable.Where
List<T>.ConvertAll
可以替换为 Enumerable.Select
Predicate<T>
可以替换为 Func<T, bool>
Converter<T,R>
可以替换为 Func<T, R>
IComparer<T>
真的应该成为代表 Func<T, T, int>
Predicate<T>
它,因为它抓住了函数使用方式的意图,并节省了一点点键入。
非泛型委托 与非泛型集合一样,由于我们具有Func和Action系列,因此非泛型委托也无济于事。我将在三个参数处截断变体。如果您有三个以上的参数,请构造一个结构并将其用作单个参数。声明用于事件处理的特定委托不是很干。
Winforms
不必在两个桌面平台之间导航会很高兴。WPF是前进的方向,因此对于拥有完整的平台级冗余感到沮丧。