Questions tagged «c#»

C#是Microsoft与.NET平台并行创建的一种多范式,托管的,垃圾回收的面向对象编程语言。

5
for vs.foreach与LINQ
当我在Visual Studio中编写代码时,ReSharper(上帝保佑它!)经常建议我以更紧凑的foreach形式更改旧式的for循环。 通常,当我接受此更改时,ReSharper会往前走一步,建议我以闪亮的LINQ形式再次更改它。 因此,我想知道:这些改进是否有真正的优势?在非常简单的代码执行中,我看不到任何速度提升(显然),但是我可以看到代码变得越来越不可读...所以我想知道:值得吗?
86 c#  linq 

11
静态测试对于单元测试而言是否普遍“邪恶”?如果是的话,为什么瑞沙珀推荐它?[关闭]
我发现只有三种方法可以对C#.NET中静态的单元测试(模拟/存根)依赖性进行测试: 鼠 TypeMock JustMock 鉴于其中有两个不是免费的,而另一个没有发布1.0版,因此模拟静态内容并不是一件容易的事。 这是否构成静态方法和此类“邪恶”(就单元测试而言)?如果是这样,为什么harsharper希望我做任何可以静态的事情?(假设重新剃刀也不是“邪恶的”。) 澄清: 我是在谈论要对方法进行单元测试并且该方法在其他单元/类中调用静态方法的情况。根据单元测试的大多数定义,如果仅让被测方法在另一个单元/类中调用静态方法,则您不是单元测试,而是集成测试。(有用,但不是单元测试。)

4
富域模型-行为如何准确地适应?
在Rich与Anemic领域模型的辩论中,互联网充满了哲学上的建议,但缺乏权威的例子。这个问题的目的是找到适当的领域驱动设计模型的明确指南和具体示例。(理想情况下为C#。) 对于一个实际示例,这种DDD实现似乎是错误的: 下面的WorkItem域模型不过是属性包,由Entity Framework用于代码优先数据库。按照福勒的说法,这是贫血的。 WorkItemService层显然是对域服务的常见误解。它包含WorkItem的所有行为/业务逻辑。Per Yemelyanov等人认为,这是程序性的。(第6页) 因此,如果以下内容是错误的,我该怎么做呢? 该行为,即AddStatusUpdate或Checkout,应该属于WorkItem类吗? WorkItem模型应具有哪些依赖关系? public class WorkItemService : IWorkItemService { private IUnitOfWorkFactory _unitOfWorkFactory; //using Unity for dependency injection public WorkItemService(IUnitOfWorkFactory unitOfWorkFactory) { _unitOfWorkFactory = unitOfWorkFactory; } public void AddStatusUpdate(int workItemId, int statusId) { using (var unitOfWork = _unitOfWorkFactory.GetUnitOfWork<IWorkItemUnitOfWork>()) { var workItemRepo = unitOfWork.WorkItemRepository; var workItemStatusRepo …

8
返回魔术值,引发异常或在失败时返回false?
有时我最终不得不为类库编写方法或属性,对于该类库,没有真正的答案不是偶然,而是失败。无法确定,无法使用,无法找到,当前无法执行或没有其他可用数据。 我认为对于这种相对非异常的情况,有三种可能的解决方案可以指示C#4失败: 返回一个没有其他含义的魔术值(例如null和-1); 抛出异常(例如KeyNotFoundException); return false并在out参数中提供实际的返回值(例如Dictionary<,>.TryGetValue)。 所以问题是:我应该在哪种非例外情况下抛出异常?而且,如果我不应该抛出:什么时候返回在实现Try*带有out参数的方法时产生的魔术值?(对我来说,该out参数似乎很脏,要正确使用该参数还需要更多工作。) 我正在寻找实际的答案,例如涉及设计准则的答案(我对Try*方法一无所知),可用性(因为我向类库提出的要求),与BCL的一致性以及可读性。 在.NET Framework基类库中,使用了所有三种方法: 返回一个没有其他含义的魔术值: Collection<T>.IndexOf 返回-1, StreamReader.Read 返回-1, Math.Sqrt 返回NaN, Hashtable.Item 返回null; 抛出异常: Dictionary<,>.Item 抛出KeyNotFoundException, Double.Parse抛出FormatException; 要么 return false并在out参数中提供实际的返回值: Dictionary<,>.TryGetValue, Double.TryParse。 请注意,正如HashtableC#中没有泛型时创建的那样,它使用object,因此可以null作为魔术值返回。但是对于泛型,在中使用了例外Dictionary<,>,而最初没有TryGetValue。见解显然在改变。 显然,Item- TryGetValue和Parse- TryParse偶是有原因的,所以我认为抛出异常的非特殊的故障是在C#4 没有这样做。但是,Try*即使存在,方法也不总是存在Dictionary<,>.Item。

11
Java开发人员是否有意识地放弃了RAII?
作为一个长期的C#程序员,我最近来了解有关资源获取即初始化(RAII)的优点的更多信息。特别是,我发现了C#习惯用法: using (var dbConn = new DbConnection(connStr)) { // do stuff with dbConn } 具有C ++等效项: { DbConnection dbConn(connStr); // do stuff with dbConn } 这意味着记住以包围资源的使用像DbConnection在一个using块是在C ++不必要!这似乎是C ++的一大优势。当您考虑一个类的实例成员类型为时,这甚至更令人信服DbConnection。 class Foo { DbConnection dbConn; // ... } 在C#中,我需要IDisposable像这样实现Foo : class Foo : IDisposable { DbConnection dbConn; public void Dispose() { dbConn.Dispose(); …
82 java  c#  c++  language-design 

10
异常,错误代码和有区别的联合
我最近开始了C#编程工作,但是我在Haskell有很多背景。 但是我知道C#是一种面向对象的语言,我不想将圆钉插入方孔中。 我阅读了Microsoft的Exception Throwing文章,其中指出: 不要返回错误代码。 但是习惯了Haskell,我一直在使用C#数据类型OneOf,将结果作为“正确”值返回,或者将错误(通常是Enumeration)作为“左侧”值返回。 这很像EitherHaskell中的约定。 在我看来,这比例外情况更安全。在C#中,忽略异常不会产生编译错误,如果未捕获到异常,它们只会冒泡并使程序崩溃。这也许比忽略错误代码并产生不确定的行为要好,但是崩溃客户的软件仍然不是一件好事,尤其是当它在后台执行许多其他重要的业务任务时。 使用时OneOf,必须非常明确地解压缩它并处理返回值和错误代码。而且,如果在调用堆栈的那个阶段不知道如何处理它,则需要将其放入当前函数的返回值中,以便调用者知道可能会导致错误。 但这似乎不是微软建议的方法。 使用OneOf代替异常来处理“普通”异常(例如“找不到文件”等)是一种合理的方法还是一种可怕的做法? 值得注意的是,我听说过异常作为控制流被认为是一种严重的反模式,因此,如果“异常”是您通常会在不结束程序的情况下处理的,那么“控制流”是否就某种方式而言呢?我了解这里有些灰色区域。 注意,我不使用OneOf“内存不足”之类的东西,但我不希望从中恢复的条件仍然会引发异常。但是我觉得这是非常合理的问题,例如未解析的用户输入本质上是“控制流”,并且可能不应引发异常。 随后的想法: 从这次讨论中,我目前要讲的内容如下: 如果您希望直接调用者catch在大多数时间都可以处理异常并继续其工作(也许通过另一条路径),则它可能应该是返回类型的一部分。Optional或OneOf在这里有用。 如果您希望直接调用方在大多数情况下不会捕获异常,请抛出异常,以免手动将异常传递到堆栈中。 如果您不确定直接呼叫者将要做什么,则可以同时提供Parse和和TryParse。
80 c#  exceptions 

6
什么时候去流利的C#?
在很多方面,我真的很喜欢Fluent接口的概念,但是使用C#的所有现代功能(初始化程序,lambda和命名参数),我发现自己在思考:“值得吗?”,“这是正确的模式吗?采用?”。任何人都可以给我(如果不是被接受的做法),至少是他们自己的经验或决策矩阵,以便何时使用Fluent模式? 结论: 到目前为止的答案有一些好的经验法则: 当操作员多于设置员时,流利的接口将提供极大帮助,因为调用从上下文传递中受益更多。 流利的接口应该被认为是api之上的一层,而不是唯一的使用方法。 lambda,初始值设定项和命名参数等现代功能可以配合使用,使流畅的界面更加友好。 这是一个使我觉得不需要的现代功能的示例。以一个(也许很差的例子)Fluent接口为例,该接口允许我创建一个Employee,例如: Employees.CreateNew().WithFirstName("Peter") .WithLastName("Gibbons") .WithManager() .WithFirstName("Bill") .WithLastName("Lumbergh") .WithTitle("Manager") .WithDepartment("Y2K"); 可以很容易地用初始化器编写,例如: Employees.Add(new Employee() { FirstName = "Peter", LastName = "Gibbons", Manager = new Employee() { FirstName = "Bill", LastName = "Lumbergh", Title = "Manager", Department = "Y2K" } }); 在本示例中,我还可以在构造函数中使用命名参数。
78 c#  .net 

17
编码指南:方法不应包含超过7个语句?
我一直在浏览《AvSol编码指南》(C#),我几乎同意所有内容,但我真的很想知道其他人对一个特定规则的看法。 AV1500 方法不应超过7条语句需要7条以上语句的方法执行的操作过多或职责过多。它还需要人的头脑来分析确切的语句,以了解代码在做什么。用不明原因的名称将其分解为多种小型且重点突出的方法。 你们大多数人都遵循这个规则吗?即使可以大大提高可读性,即使创建新方法(您的代码仍然是DRY)几乎没有什么余地?而且您的电话号码仍然低至7吗?我倾向于10。 我并不是说我到处都违反了这条规则,相反,我的方法体积小且专注于95%,但我说你永远不应该违反这条规则,这真的让我感到震惊。 我真的只是想知道每个人对永不违反此规则的看法(在编码标准上为“ 1”-永不这样做)。但是我认为您很难找到没有的代码库。

11
严格出于测试目的修改代码是否是错误的做法
我与一名程序员同事讨论关于仅修改一段可工作的代码以使其可测试(例如通过单元测试)是好是坏的做法。 我的观点是,在保持良好的面向对象和软件工程实践的范围内(当然不要“公开一切”等),这是可以的。 我同事的观点是,仅出于测试目的修改代码(有效)是错误的。 只是一个简单的示例,请考虑某些组件(用C#编写)使用的这段代码: public void DoSomethingOnAllTypes() { var types = Assembly.GetExecutingAssembly().GetTypes(); foreach (var currentType in types) { // do something with this type (e.g: read it's attributes, process, etc). } } 我建议可以修改此代码以调出另一个可以完成实际工作的方法: public void DoSomething(Assembly asm) { // not relying on Assembly.GetExecutingAssembly() anymore... } 此方法接受一个Assembly对象进行处理,从而可以通过您自己的Assembly进行测试。我的同事认为这不是一个好习惯。 什么被认为是良好且常见的做法?

8
C#中“ yield”关键字的实际使用
经过将近4年的经验,我还没有看到使用yield关键字的代码。有人可以告诉我该关键字的实际用法(以及解释)吗?如果可以,是否还有其他方法可以更轻松地实现它的功能?
76 c#  syntax 

9
为什么要使用局部类?
以我的理解,该partial关键字什么也没有做,只是允许在几个源文件之间拆分一个类。除了代码组织之外,还有其他理由吗?我已经在生成的UI类中看到了它的用法。 似乎没有理由创建整个关键字。如果一个类足够大而需要多个文件,那么它可能做得太多。我以为您也许可以用它部分地定义一个类,供其他程序员在某个地方完成,但是最好创建一个抽象类。

5
为什么不在C#中使用'using'指令?
大型C#项目上的现有编码标准包括以下规则:所有类型名称均应完全限定,从而禁止使用“ using”指令。因此,而不是熟悉的: using System.Collections.Generic; .... other stuff .... List<string> myList = new List<string>(); (这var也就不足为奇了。) 我最终得到: System.Collections.Generic.List<string> myList = new System.Collections.Generic.List<string>(); 打字量增加了134%,但没有提供任何有用的信息。在我看来,增加的100%是实际上阻碍理解的噪音(杂波)。 在30多年的编程中,我看到过一次或两次提出这样的标准,但从未实施过。它背后的原理使我无所适从。实施标准的人并不愚蠢,我认为他不是恶意的。除非我遗漏了一些东西,否则这会导致误导是唯一的其他选择。 您听说过这样的标准吗?如果是这样,其背后的原因是什么?除了“这很愚蠢”或“其他人都雇用using”之外,您还能想到其他可能说服此人取消该禁令的论点吗? 推理 禁止的原因有: 将鼠标悬停在名称上以获得完全限定的类型很麻烦。最好始终始终显示完全合格的类型。 电子邮件代码段没有完全限定的名称,因此可能很难理解。 在Visual Studio(例如Notepad ++)之外查看或编辑代码时,不可能获得完全限定的类型名称。 我的论点是,这三种情况都是很少见的,而让每个人都为解决一些罕见情况而付出混乱且难以理解的代码的代价是错误的。 我什至没有提到潜在的名称空间冲突问题,而我希望这是最主要的问题。这特别令人惊讶,因为我们有一个名称空间MyCompany.MyProject.Core,这是一个特别糟糕的主意。我很早就学会这东西命名System或Core在C#是一个快速路径的疯狂。 正如其他人指出的那样,通过重构,名称空间别名或部分限定条件可以轻松解决名称空间冲突。

7
什么时候在C#中使用抽象类代替具有扩展方法的接口?
“抽象类”和“接口”是相似的概念,其中接口是两者中比较抽象的。一个区别因素是抽象类在需要时为派生类提供方法实现。但是,在C#中,最近引入的扩展方法已减小了这种差异因素,该扩展方法使得可以为接口方法提供实现。另一个区别因素是,一个类只能继承一个抽象类(即没有多重继承),但可以实现多个接口。这使接口的限制更少,更加灵活。因此,在C#中,什么时候应该使用抽象类而不是具有扩展方法的接口? 接口+扩展方法模型的一个著名示例是LINQ,其中为IEnumerable通过多种扩展方法实现的任何类型提供了查询功能。


8
命名问题:“ Isomething”是否应重命名为“ Something”?[关闭]
Bob叔叔在“ 干净代码”中有关名称的章节中建议您避免使用名称编码,主要是关于匈牙利表示法。他还特别提到I从接口中删除前缀,但没有显示此示例。 让我们假设以下内容: 接口的使用主要是通过依赖注入实现可测试性 在许多情况下,这导致与单个实施者具有单个接口 因此,例如,这两个应命名为什么?Parser和ConcreteParser?Parser和ParserImplementation? public interface IParser { string Parse(string content); string Parse(FileInfo path); } public class Parser : IParser { // Implementations } 还是在这样的单一实现案例中忽略该建议?

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.