这是一个标准方案:
if(string.IsNullOrEmpty(Configuration.AppSettings["foobar"]))
throw new SomeStandardException("Application not configured correctly, bozo.");
Run Code Online (Sandbox Code Playgroud)
问题是,我不完全确定应该是哪个例外SomeStandardException.
我仔细阅读了3.5框架,发现了两个可能的候选人:ConfigurationException和ConfigurationErrorsException.
System.Configuration.ConfigurationException
发生配置系统错误时引发的异常.
备注
该ConfigurationException如果应用程序试图读取或写入数据到配置文件,但不成功则抛出异常.可能的原因可能包括配置文件中格式错误的XML,文件权限问题以及值无效的配置属性.注意:
ConfigurationException维护该对象是为了向后兼容.该ConfigurationErrorsException对象替换配置系统.
这个例外实际上听起来非常适合我所需要的,但它已被标记为过时,所以,ixnay on atthay.
这让我们彻底迷惑ConfigurationErrorsException:
System.Configuration.ConfigurationErrorsException
当前值不是EnableSessionState值之一.
如您所见,其文档完全没用.(在本地和在线帮助中都是如此.)对课程本身的检查表明,对于我想要的东西来说,这是一种极端的过度杀伤力.
简而言之,我需要一个标准异常,当应用程序配置设置丢失或包含无效值时应抛出该异常.你认为框架有一个例外,它允许应用程序使用它.(它显然没有,但它被标记为已过时,并且被替换的东西多范围较大.)
你们有什么解决方案,如果有的话,我们将不得不将其吸收并为此推出自己的例外情况?
有些人问我是否可以提供默认值,然后继续.在某些情况下,是的,在这些情况下,不会抛出异常.但是,对于某些设置,这将不适用.例如:数据库服务器名称和凭据,身份验证服务器以及安装的第三方应用程序的路径.
还值得注意的是,我主要处理的应用程序是以批处理模式运行的控制台应用程序,我希望它抛出一个由main方法捕获的异常,并在没有正确配置的情况下正确记录.(这是我继承的遗留代码,目前只是假设一切都很好.)
我清楚地记得,有一次,微软推动的指导原则是将"Base"后缀添加到抽象类中,以避免它是抽象的事实.因此,我们有类,如System.Web.Hosting.VirtualFileBase,System.Configuration.ConfigurationValidatorBase,System.Windows.Forms.ButtonBase,,当然,System.Collections.CollectionBase.
但是我注意到,最近,框架中的许多抽象类似乎都没有遵循这个约定.例如,以下类都是抽象的,但不遵循此约定:
System.DirectoryServices.ActiveDirectory.DirectoryServer
System.Configuration.ConfigurationElement
System.Drawing.Brush
System.Windows.Forms.CommonDialog
这就是我几秒钟内就可以鼓起来的东西.所以我去查看官方文档说的内容,以确保我没有疯狂.我在开发类库的设计指南中找到了MSDN上的类,结构和接口的名称.奇怪的是,我没有提到在抽象类名称的末尾添加"Base"的指南.该框架的1.1版已不再适用该指南.
那么,我输了吗?该指南是否存在?是不是一言不发就被遗弃了?在过去的两年里,我一直在为自己创造长篇名字吗?
有人在这里给我一个骨头.
更新 我不是疯了.该指南已存在.Krzysztof Cwalina在2005年抱怨它.
所以,(看似)突然之间,我的项目开始得到编译器警告1685:
预定义类型"System.Runtime.CompilerServices.ExtensionAttribute"在全局别名中的多个程序集中定义; 使用'c:\ Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll'中的定义
困惑,我研究了MSDN文章,找出其原因.这是我发现的信息:
Visual C#参考:错误和警告编译器警告(级别1)CS1685
错误消息预定义类型"System.type name"在全局别名中的多个程序集中定义; 使用'文件名'中的定义
在两个程序集中找到预定义的系统类型(如System.int32)时,会发生此错误.这种情况的一种方法是,如果您从两个不同的位置引用mscorlib,例如尝试并行运行.Net Framework版本1.0和1.1.
编译器将仅使用其中一个程序集中的定义.编译器仅搜索全局别名,不搜索库定义/引用.如果已指定/ nostdlib,则编译器将搜索Object,并在将来启动所有搜索到找到Object的文件中的预定义类型.
现在我真的在挠头.
我没有运行两个不同版本的.NET Framework(除非你算上2.0和3.5).
我没有引用可能让我怀疑的任何奇怪的集会.
我不记得对我的应用程序进行任何更改会刺激这种变化.
我已经验证所有组件都针对.NET Framework版本v2.0.50727.
我愿意接受有关如何纠正此问题的建议或想法.我将警告视为错误,这让我发疯.
真正让我烦恼的是,我不知道它为什么会发生.发生的事情应该有一个可辨别的原因,我应该知道它们为什么会发生.如果我无法解释,我无法准确地解决它.猜测工作永远不会令人满意.
该应用程序很简单,由类库和Windows窗体应用程序组成.
AC#类库DLL提供封装数据库访问的基本功能.此DLL引用以下组件:
提供UI的AC#Windows Forms应用程序.此应用程序引用以下组件:
如果您需要更多信息,请告诉我,我很乐意提供.
我是在尊敬的John Skeet先生的要求下重新发布这个问题的,他建议我设计一个简单的测试程序,隔离并演示我遇到的问题并重新发布问题.这个问题多起来了这一个,所以请原谅我,如果这一切听起来很熟悉.您可以从中收集有关此问题的额外详细信息.
我遇到的问题Assert.Throws<T>来自NUnit 2.5.9.有时,它无法捕获TestDelegate调用的方法中抛出的任何异常.我已经在下面的代码中以可重现的方式确定了这种行为.(尽管如此,这可能是Fails On My Machine™的案例.
为了重现错误,我创建了一个包含两个C#DLL项目的解决方案:
SqlCommand,填充其参数并ExecuteScalar在其上调用所需的逻辑.该项目不包括其他参考.当我在调试器中单步执行测试时,我会观察到以下内容:
Assert.Throws正确调用ExecuteScalar<T>扩展方法.ExecuteScalar<T> 测试其参数的空值.throw new ArgumentNullException(...).throw,应用程序的控制权不会立即转移到Assert.Throws.相反,它继续在下一行ExecuteScalar<T>.下面给出了隔离此行为的源代码.
扩展方法
namespace NUnit_Anomaly
{
using System;
using System.Data;
using System.Data.SqlClient;
public static class Class1
{
public static T ExecuteScalar<T>(this SqlConnection connection, string sql)
{
if (connection == null)
{
throw new ArgumentNullException("connection");
}
if (sql == …Run Code Online (Sandbox Code Playgroud) 考虑以下控件(为简洁而剪切):
public partial class ConfigurationManagerControl : UserControl
{
public Func<string, bool> CanEdit { get; set;}
public Func<string, bool> CanDelete { get; set; }
public Dictionary<string, string> Settings
{
get { return InnerSettings; }
set
{
InnerSettings = value;
BindData();
}
}
private Dictionary<string, string> InnerSettings;
private void OnListIndexChanged(object sender, EventArgs e)
{
this.EditButton.Enabled = false;
this.DeleteButton.Enabled = false;
var indices = this.List.SelectedIndices;
if (indices.Count != 1)
{
return;
}
var index = indices[0];
var item = this.List.Items[index];
if (this.CanEdit != …Run Code Online (Sandbox Code Playgroud) 在我们(相当大和旧)的ASP.NET应用程序中,我们使用大量页面加载到框架,iframe和模态对话框中(使用window.showModalDialog).我们开始看到上面的错误很多,我似乎无法在任何地方找到一个合理的解释.
弹出窗口拦截器.不.我们没有运行它们.甚至没有内置阻止器.
可信区域.不.该应用程序现在在LocalHost上运行,它位于受信任的站点列表中.
迷路宇宙射线.可能,但不太可能.这太过一致了.
我也终于找到埋在微软的网站上的错误消息,一些尘封的大部头有关检索自动化错误消息的信息.在其中,他们谈论的是Excel,他们说:"在这个例子中,Microsoft Excel是服务器应用程序.一旦工作簿对象被销毁(或关闭),就会生成错误. "
这可能就像我对错误原因的解释一样接近,没有真正的具体解释.有人试图在引用它之后使用某些东西.奇怪的是,你仍然可以在屏幕上看到窗户.然而奇怪的是,这种怀疑嫌我接受的答案来的这个.
所以这就是发生的事情.
如果有人可以告诉我为什么会这样(代码在FF中工作),我会很感激.
我们的组织拥有Azure DevOps测试计划服务.
此特定用户是团队成员,其成员具有以下权限设置为允许(继承).
尽管如此," 配置"选项未显示在" 测试计划"下的左侧导航面板中,因此用户无法查看或以其他方式管理测试配置.
团队的其他成员确实看到了" 配置"菜单项.
我假设这是基于权限的,并且特定于此用户,但是当我检查用户的权限时,它们都被设置为允许(继承),所以我无法弄清楚什么是错的.
有人能提供有关解决方案或原因的任何见解吗?
我还在为DataCamp for R上课,所以如果这个问题看起来很天真,请原谅我.
考虑以下(非常人为的)样本:
library(dplyr)
library(tibble)
type <- c("Dog", "Cat", "Cat", "Cat")
name <- c("Ella", "Arrow", "Gabby", "Eddie")
pets = tibble(name, type)
name <- c("Ella", "Arrow", "Dog")
type <- c("Dog", "Cat", "Calvin")
favorites = tibble(name, type)
anti_join(favorites, pets, by = "name")
setdiff(favorites, pets, by = "name")
Run Code Online (Sandbox Code Playgroud)
这两个都返回完全相同的数据:
> anti_join(favorites, pets, by = "name")
# A tibble: 1 × 2
name type
<chr> <chr>
1 Dog Calvin
> setdiff(favorites, pets, by = "name")
# A tibble: 1 × 2 …Run Code Online (Sandbox Code Playgroud) 这一直困扰着我.也许对.NET内部有一些核心知识的人可以向我解释一下.
假设我按如下方式定义枚举:
public enum Foo
{
Eenie = 1,
Meenie = 2,
Miney = 3,
Moe = 4
}
Run Code Online (Sandbox Code Playgroud)
现在,也假设在我的代码中的某个地方,我有以下代码:
int bar = (Foo)5;
Run Code Online (Sandbox Code Playgroud)
这将编译得很好,并且不会引发任何异常,即使值5显然不是在中定义的有效值Foo.
或者,请考虑以下事项:
public void ProcessFoo(Foo theFoo)
{
// Do processing
}
public static void Main()
{
ProcessFoo((Foo)5);
}
Run Code Online (Sandbox Code Playgroud)
再次,也不例外.
在我看来,这应该导致类型不匹配异常,因为5不是a Foo.但设计师选择不这样做.
现在,我已经编写了一个可以验证这种情况的扩展方法,并且调用它以确保就是这种情况并没有什么大不了的,但是我必须使用反射来做到这一点(包括所有性能损失和诸如此类的因素) ).
那么,有什么令人信服的理由可能导致决定没有检查枚举?
供参考,来自Enum类的MSDN文档:
定义将枚举常量作为值的方法或属性时,请考虑验证该值.原因是您可以将数值转换为枚举类型,即使该枚举类型中未定义该数值也是如此.
我们有一个最近引入的表(Organization_XREF),它包含两个外键列(Parent_ID和Child_ID),它们都引用OrganizationIDOrganization表中的同一个主键列():

当我们通过此关系运行EF Reverse POCO Code First Generator时,它会在Organization_OrganizationConfiguration类中生成HasMany关系,如下所示:
HasMany(t => t.Organization_Organization).WithMany(t => t.Organization_Organization).Map(m =>
{
m.ToTable("Organization_XREF", schema);
m.MapLeftKey("ChildId");
m.MapRightKey("ParentId");
});
Run Code Online (Sandbox Code Playgroud)
此代码将无法编译.编译器无法推断HasMany的参数类型,可能是因为没有为Organization_Organization模型生成Organization_Organization属性.
有没有其他人遇到过类似的问题?你是怎么解决这个问题的?这对我们来说是一个关键问题,因为它破坏了我们的API.