Questions tagged «c#»

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



1
OSS项目中的集成测试-如何处理带有身份验证的第三方?
我的一个开源项目是一个备份工具,该工具可从GitHub,Bitbucket等进行脱机存储库备份。 它调用托管者的API来获取存储库列表,然后使用Git / Mercurial /任何克隆/将存储库拉到本地计算机。 因此,我在集成测试中通过身份验证调用了GitHub API。 (并且当克隆/拉动功能完成时,可能会有测试从GitHub克隆存储库,并且还需要进行身份验证) 我创建了一个用户和一个组织,专门用于这些集成测试。 问题:我不能只是在源代码中的某个地方对密码进行硬编码,因为它是开源的,并且代码在GitHub上是公开的。 我现在在做什么 在测试中,我从环境变量中获取所有用户名,密码和存储库名称。 这是一个例子: config.Name = TestHelper.EnvVar("GithubApiTests_Name"); config.Password = TestHelper.EnvVar("GithubApiTests_PW"); (TestHelper.EnvVar是一个帮助程序方法,它获取环境变量的值并在不存在环境变量时引发异常) 然后,我有一个批处理文件,用于设置这些环境变量。 真正的(environment-variables.bat)在构建脚本中以及在执行测试之前被调用,但是在源代码控制中被忽略,因此它实际上不在我的存储库中。 什么是源控制environment-variables.bat.sample,它设定了相同的环境变量,而是用假密码: rem copy/rename this file to environment-variables.bat echo Setting environment variables for integration tests... set GithubApiTests_Name=scm-backup-testuser set GithubApiTests_OrgName=scm-backup-testorg set GithubApiTests_PW=not-the-real-password set GithubApiTests_Repo=scm-backup 因此,我可以将存储库克隆到我的计算机上,将此文件重命名为environment-variables.bat,用真实的密码替换假密码,所有集成测试都将起作用。 这也适用于持续集成-我正在使用AppVeyor,并且可以在Web UI中设置这些环境变量。 我对此不满意 我认为这对于OSS项目不是一个好的解决方案,尤其是对于该项目不是这样: 从理论上讲,我的项目的贡献者现在可以通过以下方式运行集成测试: …

3
将构建器和流体接口与对象初始化器一起使用是否有意义?
在Java和C#中,您可以创建具有可在初始化时设置的属性的对象,方法是定义带参数的构造函数,构造对象后定义每个属性,或使用builder / fluid接口模式。但是,C#3引入了对象和集合初始化程序,这意味着构建器模式在很大程度上没有用。在没有初始化程序的语言中,可以实现一个生成器,然后像这样使用它: Vehicle v = new Vehicle.Builder() .manufacturer("Toyota") .model("Camry") .year(1997) .colour(CarColours.Red) .addSpecialFeature(new Feature.CDPlayer()) .addSpecialFeature(new Feature.SeatWarmer(4)) .build(); 相反,在C#中,可以这样写: var vehicle = new Vehicle { Manufacturer = "Toyota", Model = "Camry", Year = 1997, Colour = CarColours.Red, SpecialFeatures = new List<SpecialFeature> { new Feature.CDPlayer(), new Feature.SeatWarmer { Seats = 4 } …

4
保证不变性是公开字段而不是公开属性的理由吗?
C#的一般指导原则是始终在公共领域使用属性。这很有意义-通过公开一个字段,您将公开许多实现细节。通过一个属性,您可以封装该详细信息,从而使其在使用代码中不会被隐藏,并且实现更改与接口更改脱钩。 但是,我想知道在处理readonly关键字时有时是否存在此规则的有效例外。通过将此关键字应用于公共领域,可以额外保证:不变性。这不仅是实现细节,不变性是用户可能感兴趣的东西。使用readonly字段使其成为公共合同的一部分,并且在将来的更改或继承中也不会破坏,而不必修改公共接口。那是财产所不能提供的。 那么,readonly在某些情况下,确保不变性是在属性上选择字段的合法理由吗? (为澄清起见,我当然不是说您应该总是仅因为该字段恰好是不可变的而做出此选择,只有当该字段作为类设计的一部分是有意义的并且打算将不可变性包括在其合同中时才使用。我最感兴趣的答案是侧重于此是否合理,而不是在某些情况下不合理(例如,当您需要将该成员放在interface或希望进行延迟加载时)。

3
基类中的抽象属性,强制程序员对其进行定义
我正在使用嵌入式设备的状态模式进行编码。我有一个称为State的基类/抽象类,然后每个离散(具体)状态类都实现了抽象State类。 在状态类中,我有几种抽象方法。如果我不在离散(具体)类中实现抽象方法,Visual Studio将给出如下错误: ...错误1'myConcreteState'未实现继承的抽象成员'myAbstractState' 现在:我正在尝试为每个名为StateName的州创建String属性。每当创建新的具体类时,都需要定义StateName。如果不使用VS,我希望VS抛出错误。有没有简单的方法可以做到这一点? 我已经在抽象/基类中尝试过此操作: public abstract string StateName { get; set; } 但是我不需要在每个州中实现Get和Set方法。 修订的问题:在理想情况下,将要求每个状态类都具有StateName定义并从抽象基类继承。 StateName = "MyState1"; //or whatever the state's name is 如果缺少该语句,则Visual Studio将生成如上所述的错误。这可能吗?如果可以,怎么办?

2
我可以使用分离但相等的对象更新附加对象吗?
我从外部API检索电影数据。在第一阶段,我将抓取每部电影并将其插入我自己的数据库中。在第二阶段中,我将使用API​​的“更改” API定期更新数据库,我可以查询该API以查看哪些电影的信息已更改。 我的ORM层是实体框架。Movie类如下所示: class Movie { public virtual ICollection<Language> SpokenLanguages { get; set; } public virtual ICollection<Genre> Genres { get; set; } public virtual ICollection<Keyword> Keywords { get; set; } } 当我有一部需要更新的电影时,就会出现问题:我的数据库会认为正在跟踪的对象以及从update API调用接收到的新对象都是不同的对象,而无视.Equals()。 这引起了一个问题,因为当我现在尝试使用更新的影片来更新数据库时,它将插入数据库而不是更新现有的影片。 我以前在语言方面遇到过这个问题,我的解决方案是搜索附加的语言对象,将它们与上下文分离,将其PK移至更新的对象,然后将其附加到上下文。当SaveChanges()正在执行,它将基本上取代它。 这是一种很臭的方法,因为如果我继续对Movie对象使用这种方法,则意味着我必须分离电影,语言,流派和关键字,在数据库中查找每个人,传输其ID并插入新对象。 有没有办法更优雅地做到这一点?理想情况下,我只想将更新的影片传递给上下文,并让该影片根据该Equals()方法选择正确的影片进行更新,更新其所有字段并针对每个复杂对象:根据其自己的Equals()方法再次使用现有记录,并插入它尚不存在。 我可以通过.Update()在每个复杂对象上提供方法来跳过分离/附加,可以结合使用这些方法来检索所有附加对象,但这仍然需要我检索每个现有对象然后进行更新。

2
事件的发送者是否应该始终是通用对象?
使用C#编写事件时,建议以以下形式创建委托: delegate XEventHandler(object sender, XEventArgs e); 我的问题是关于代表的第一个论点object sender。一定要一定要通用object吗?具有类型的发送方object总是会导致与此类似的代码。 val = ((ConcreteType)sender).Property; 或者,甚至更冗长, ConcreteType obj = sender as ConcreteType if (obj != null) { ... } 反对强类型发送者的一种说法是,其他对象可以转发事件而不必担心类型。尽管这在GUI环境中可能有意义,但是我不确定它是否可以在GUI之外受益。 如果始终知道发送方的类(至少是抽象类)怎么办?例如,如果我实现ListChanged的一个抽象事件List类,而如果其他类要继承它(例如LinkedList,ArrayList),是这一切的权利界定与类型的发件人我的委托List? delegate ListChangedEventHander(List sender, ListChangedEventArgs e); 还是将常规object sender类型更改为更特定的类型会有不利影响?
10 c#  event 

1
在C#5.0中模糊异步和常规函数之间的界限
最近,我似乎对C#5.0 的惊人异步等待模式不够了解。我这辈子去哪了 我对简单的语法感到非常兴奋,但是我遇到了一个小困难。我的问题是异步函数的声明与常规函数完全不同。由于只有异步函数可以等待其他异步函数,因此当我尝试将一些旧的阻止代码移植到异步时,我产生了必须转换的函数的多米诺骨牌效应。 人们一直称其为僵尸大批出没。当异步在您的代码中被咬时,它将不断变得越来越大。移植过程并不困难,只需将其async放入声明中并用来包装返回值Task<>。但是在移植旧的同步代码时,一遍又一遍地执行此操作很烦人。 在我看来,如果两种函数类型(异步和普通旧同步)具有完全相同的语法,那将是自然得多的。如果是这种情况,移植将花费零的精力,我可以在两种形式之间轻松切换。 我认为如果遵循以下规则,这可能会起作用: 异步函数不再需要async声明。他们的返回类型不必包装Task<>。编译器将在编译期间自行识别异步函数,并根据需要自动执行Task <>包装。 不再需要对异步函数进行“一劳永逸”的调用。如果要调用异步函数,则需要等待它。无论如何,我几乎都不用一劳永逸,疯狂的比赛条件或僵局的所有例子似乎总是基于它们。我认为他们与我们试图利用的同步思维过于混乱和“脱节”。 如果您真的不能一劳永逸,那将有特殊的语法。无论如何,它不会成为我正在谈论的简单统一语法的一部分。 您需要表示异步调用的唯一关键字是await。如果您正在等待,则该调用是异步的。如果您不这样做,则该呼叫是普通的老式同步呼叫(请记住,我们不再具有即兴即弃的功能)。 编译器将自动识别异步函数(因为它们不再有特殊的声明了)。规则4使得此操作非常简单-如果函数await内部有调用,则它是异步的。 能行吗?还是我错过了什么?这种统一的语法更加流畅,可以完全解决僵尸的侵扰。 一些例子: // assume this is an async function (has await calls inside) int CalcRemoteBalanceAsync() { ... } // assume this is a regular sync function (has no await calls inside) int CalcRemoteBalance() { ... } // now …

1
拥有TFS后,为什么还要在PowerShell中创建部署脚本?
我正在尝试自动部署/持续集成,并与团队负责人进行了交谈。 我告诉他我正在研究如何在PowerShell中创建构建/部署脚本,他说使用GUI在TFS中设置自动部署非常容易,我应该进行研究。除了致力于从VS进行源代码控制外,我对TFS零经验。 在哪种情况下,TFS会失败?使用PowerShell进行自动部署会更好吗?选择PowerShell而不使用TFS还有哪些其他原因和优势? 还有另一件事:例如,我可以运行第三方工具来缩小TFS中的JS文件吗? 我可能想到的PowerShell的一些优点: PowerShell提供最大的灵活性 您可以轻松切换到另一个源代码管理系统,例如Mercurial 这些脚本比TFS生成的脚本更易于维护 PowerShell轻巧:您可以在任何PC上运行脚本

6
为什么要在变量使用位置附近声明变量?
我听说有人说变量应该声明得尽可能接近其用法。我不明白 例如,此政策建议我应该这样做: foreach (var item in veryLongList) { int whereShouldIBeDeclared = item.Id; //... } 但是可以肯定的是,这意味着int每次迭代都会产生创建新的开销。使用会不会更好: int whereShouldIBeDeclared; foreach (var item in veryLongList) { whereShouldIBeDeclared = item.Id; //... } 请有人能解释一下吗?
10 c#  .net  variables 

3
我是否仍需要使用定点数来保证计算机在数学运算中获得相同的结果?
有人告诉我,大多数现代计算机遵循相同的浮点标准,这是否意味着如果输入相同,对于给定的数学运算,它们都将获得相同的浮点答案? 我之所以问是因为我正在研究在网络上制作RTS游戏,并且同步数百个单位的位置听起来是一种不好的方法。 因此,如果我仅发送输入,则需要确保所有客户端通过从这些输入运行模拟来获得相同的结果。 我读到较旧的RTS游戏使用定点算法,但是我不知道现代计算机是否都遵循相同的标准?我还被告知,尽管不精确,但对于相同的输入,浮点数的结果是确定的(我想这意味着遵循相同标准的任何计算机都会得到相同的不精确结果吗?)。 即使计算机遵循相同的浮点标准,仍然存在偏差吗? 我用C#编写游戏,但不确定是否重要,以为我还是会提到它。

3
为什么在函数式编程中不鼓励使用赋值运算符或循环?
如果我的函数满足以下两个要求,我相信Sum 返回给定条件下列表项的总和的函数,其中项在给定条件下的评估结果为true,这称为纯函数,不是吗? 1)对于给定的一组i / p,无论何时调用函数,都将返回相同的o / p 2)它没有任何副作用 public int Sum(Func<int,bool> predicate, IEnumerable<int> numbers){ int result = 0; foreach(var item in numbers) if(predicate(item)) result += item; return result; } 范例: Sum(x=>x%2==0, new List<int> {1,2,3,4,5...100}); 我之所以问这个问题,是因为我几乎每时每刻都在建议人们避免使用赋值运算符和循环,因为它是命令式编程风格。那么上面的示例在函数编程的上下文中使用循环和赋值运算符会出错吗?

6
如果我的对象是可变的,在函数式编程的上下文中会出什么问题?
我可以看到可变对象与不可变对象(如不可变对象)的好处,消除了由于共享和可写状态而导致的多线程编程中的许多疑难解答问题。相反,可变对象有助于处理对象的身份,而不是每次都创建新的副本,因此特别是对于较大的对象,还可以提高性能和内存使用率。 我想了解的一件事是,在函数式编程的上下文中拥有可变对象可能会出错。像告诉我的要点之一是,以不同顺序调用函数的结果不是确定性的。 我正在寻找一个真正的具体示例,其中很明显在函数编程中使用可变对象会导致什么问题。基本上,如果它不好,那么不管是面向对象还是功能编程范例都不好,对吗? 我相信,在我自己的发言下面,我可以回答这个问题。但是我仍然需要一些例子,以便我能更自然地感受到。 OO通过诸如封装,多态等工具帮助管理依赖性并编写更容易维护的程序。 函数式编程也具有促进可维护代码的动机,但是通过使用样式消除了使用OO工具和技术的需要-我认为其中之一是通过最小化副作用,纯函数等。

3
如果反模式
我在此博客上阅读了有关“如果-如果反模式”的信息,但我不确定我是否理解为什么它是反模式。 foreach (string filename in Directory.GetFiles(".")) { if (filename.Equals("desktop.ini", StringComparison.OrdinalIgnoreCase)) { return new StreamReader(filename); } } 问题1: 是因为return new StreamReader(filename);里面for loop吗?还是for在这种情况下不需要循环的事实? 正如博客作者所指出的那样,这种方式的疯狂程度较小: if (File.Exists("desktop.ini")) { return new StreamReader("desktop.ini"); } 两者都处于竞争状态,因为如果在创建之前删除文件StreamReader,您将得到一个File­Not­Found­Exception。 问题2: 要修复第二个示例,您是否要在不使用if语句的情况下重新编写它,而是StreamReader使用try-catch块将其包围,并且如果引发了File­Not­Found­Exception您在该catch块中进行相应的处理?

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.