这是一个非常好的问题,因为我已经看到许多C ++开发人员编写了糟糕的C#代码。
最好不要将C#视为“具有更好语法的C ++”。它们是不同的语言,在您的思维中需要不同的方法。C ++迫使您不断思考CPU和内存将要做什么。C#不是那样的。专门设计C#的目的是使您不必考虑CPU和内存,而可以考虑要编写的业务领域。
我看到的一个例子是,许多C ++开发人员都喜欢使用for循环,因为它们比foreach更快。这在C#中通常不是一个好主意,因为它限制了要迭代的集合的可能类型(因此限制了代码的可重用性和灵活性)。
我认为,从C ++调整为C#的最佳方法是尝试从不同的角度进行编码。刚开始这会很困难,因为多年来,您将完全习惯于使用大脑中的“ CPU和内存在做什么”线程来过滤所编写的代码。但是在C#中,您应该考虑业务域中对象之间的关系。“我想做什么”而不是“计算机在做什么”。
如果您要对对象列表中的所有内容执行某项操作,而不是在列表上编写for循环,请创建一个采用IEnumerable<MyObject>
and并使用foreach
循环的方法。
您的具体示例:
控制需要确定性清除的资源(例如文件)的生命周期。用手可以很容易地使用它,但是当资源所有权正在转移时如何正确使用它?在C ++中,我只使用共享指针,并让它在适当的时候处理“垃圾回收”。
绝对不要在C#中执行此操作(尤其是在线程之间)。如果您需要对文件进行某些操作,请一次在一个地方进行处理。可以编写一个包装类来管理在类之间传递的非托管资源,这是很好的做法(也是一种很好的做法),但是不要尝试在线程之间传递File并让单独的类来写/读/关闭/打开它。不要共享非托管资源的所有权。使用该Dispose
模式进行清理。
不断为特定泛型的重写功能而苦苦挣扎(我喜欢C ++中的部分模板专门化之类的东西)。我应该放弃使用C#进行通用编程的任何尝试吗?也许泛型是有目的的,除了特定领域的问题外,使用C并不是C#风格?
C#中的泛型被设计为泛型。泛型的专业化应由派生类处理。List<T>
如果为a List<int>
或a,为什么行为应有所不同List<string>
?上的所有操作List<T>
都是通用的,因此适用于任何操作 List<T>
。如果要更改上.Add
方法的行为List<string>
,请创建一个派生类MySpecializedStringCollection : List<string>
或组合类MySpecializedStringCollection : IList<string>
,该派生类或组合类在内部使用泛型,但以不同的方式进行操作。这可以帮助您避免违反《里斯科夫换人原则》,并避免对使用您的班级的其他人大加指责。
类似宏的功能。虽然通常是个坏主意,但对于某些问题领域,没有其他解决方法(例如,对语句的条件评估,例如只应运往Debug版本的日志)。没有它们意味着我需要放置更多if(condition)样板,并且在触发副作用方面仍然不相等。
正如其他人所说,您可以使用预处理程序命令来执行此操作。属性甚至更好。通常,属性是处理不是类的“核心”功能的事物的最佳方法。
简而言之,在编写C#时,请记住,您应该完全考虑业务领域,而不是CPU和内存。如有必要,您可以稍后进行优化,但是您的代码应反映您要映射的业务原则之间的关系。
C#
用于生成其他代码。您可以读取一个CSV
或一个XML
或一个文件作为输入并生成一个C#
或一个SQL
文件。这比使用功能宏更强大。