我有一个C#字符串扩展方法,它应返回IEnumerable<int>
字符串中子字符串的所有索引.它完美地用于其预期目的,并返回预期的结果(由我的一个测试证明,虽然不是下面的一个),但另一个单元测试发现它有一个问题:它不能处理空参数.
这是我正在测试的扩展方法:
public static IEnumerable<int> AllIndexesOf(this string str, string searchText)
{
if (searchText == null)
{
throw new ArgumentNullException("searchText");
}
for (int index = 0; ; index += searchText.Length)
{
index = str.IndexOf(searchText, index);
if (index == -1)
break;
yield return index;
}
}
Run Code Online (Sandbox Code Playgroud)
这是标记问题的测试:
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Extensions_AllIndexesOf_HandlesNullArguments()
{
string test = "a.b.c.d.e";
test.AllIndexesOf(null);
}
Run Code Online (Sandbox Code Playgroud)
当测试针对我的扩展方法运行时,它会失败,标准错误消息表明该方法"没有抛出异常".
这很令人困惑:我已明确传入null
函数,但由于某种原因,比较null == null
正在返回false
.因此,不会抛出异常并且代码会继续.
我已经确认这不是测试的错误:在我的主项目中通过调用Console.WriteLine
null比较if
块运行该方法时,控制台上没有显示任何内容,并且catch
我添加的任何块都没有捕获到任何异常.而且,使用string.IsNullOrEmpty
而不是== null …
如果我运行此代码:
Console.WriteLine( String.Format( "{0}", null ) );
Run Code Online (Sandbox Code Playgroud)
我得到一个,ArgumentNullException
但如果我运行此代码:
String str = null;
Console.WriteLine( String.Format( "{0}", str ) );
Run Code Online (Sandbox Code Playgroud)
它运行得很好,输出是一个空字符串.
现在两件看起来相当于我 - 他们都传递了一个空引用String.Format()
但行为是不同的.
如何识别不同的行为?
我尝试使用此代码添加b
到books
:
IEnumerable<Book> books =null;
foreach (Book b in context.Books.AsEnumerable())
if (someConditions)
books = books.Concat(new[] {b});
Run Code Online (Sandbox Code Playgroud)
但在最后一行代码中给出了这个错误:
System.ArgumentNullException:值不能为null.参数名称:首先
似乎null
Collection
无法连接.我使用EF,所以我应该如何初始化我Collection
没有东西,我可以连接到它?
c# linq linq-to-entities concatenation argumentnullexception
有什么情况throw
可以避免可以避免的错误吗?
我正在考虑DivideByZeroException
和ArgumentNullException
例如:
double numerator = 10;
double denominator = getDenominator();
if( denominator == 0 ){
throw new DivideByZeroException("You can't divide by Zero!");
}
Run Code Online (Sandbox Code Playgroud)
有没有理由抛出这样的错误?
注意:我不是在谈论捕捉这些错误,而是专门知道是否有充分理由抛弃这些错误.
只是重新评估:
我知道在我给你的例子中你可能会更好地处理错误.也许这个问题应该改写一下.是否有任何原因导致throw
其中一个错误,而不是在此位置处理它.
c# exception-handling argumentnullexception dividebyzeroexception
好吧,几个月前我问了一个关于C和C++的类似问题,但由于整个"Windows Phone"的缘故,我最近一直在关注C#.
那么,在C#中,是否应该在方法边界检查NULL?我认为这与C和C++不同,因为在C#中,通常可以确定给定的引用是否有效 - 编译器将阻止在任何地方传递未初始化的引用,因此唯一剩下的可能错误是它为null .此外,在.NET Framework中为这些事物定义了一个特定的异常,即ArgumentNullException,它似乎编写了程序员认为在传递无效null时应该获得的异常.
我的个人意见再次表明,打电话的人打破了这个问题,而且打电话的人应该把NRE扔到他们面前,直到几天结束.但是,我对这方面的不太确定,而不是我在本地代码领域 - 在这方面,与C或C++相比,C#的编程风格完全不同.
那么......你应该在C#方法中检查空参数吗?
我一直在研究Scott Guthrie关于ASP.NET MVC Beta 1的优秀帖子.在其中,他展示了对UpdateModel方法所做的改进以及它们如何改进单元测试.我已经重新创建了一个类似的项目,但是当我运行包含对UpdateModel的调用的UnitTest时,我会收到一个名为controllerContext参数的ArgumentNullException.
这是相关的位,从我的模型开始:
public class Country {
public Int32 ID { get; set; }
public String Name { get; set; }
public String Iso3166 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
控制器动作:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Int32 id, FormCollection form)
{
using ( ModelBindingDataContext db = new ModelBindingDataContext() ) {
Country country = db.Countries.Where(c => c.CountryID == id).SingleOrDefault();
try {
UpdateModel(country, form);
db.SubmitChanges();
return RedirectToAction("Index");
}
catch {
return View(country);
}
}
}
Run Code Online (Sandbox Code Playgroud)
最后我的单元测试失败了:
[TestMethod]
public void Edit() …
Run Code Online (Sandbox Code Playgroud) asp.net-mvc updatemodel argumentnullexception controllercontext
我习惯于检查方法的参数是否为null(然后继续抛出异常),我几乎不再考虑它了.如果参数是引用类型,那么它就在那里:
if(arg == null)
throw new ArgumentNullException(nameof(arg));
Run Code Online (Sandbox Code Playgroud)
但是,如果我要立即使用arg怎么办?我应该检查一下吗?我的意思是,如果我不这样做,无论如何,envinroment将为我抛出(NullReferenceException).
例如:
public int DoStuff(object o)
{
return o.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
我可以轻松地添加null检查:
public int DoStuff(object o)
{
if(o == null)
throw new ArgumentNullException(nameof(o));
return o.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)
但在这两种情况下都会抛出异常(在几乎完全相同的行中,出于调试目的).唯一的区别是类型.
问题:在具有单个引用类型参数的公共方法上,如果我要立即使用该参数,我是否仍应检查它是否是?null
所以我正在尝试更改Windows 8应用程序中的帧.我尝试按照本页的教程,但我一直得到同样的错误.
我在线上得到了一个ArgumentNullException:
frameState[_pageKey] = pageState;
Run Code Online (Sandbox Code Playgroud)
在LayoutAwarePage.cs类中,在OnNavigatedFrom方法中.
现在我不确定为什么会出现这个错误,因为我觉得在我的代码中没有任何东西可以导致它.我的按钮onclick函数有以下代码:
DateTime chosenDateTime = new DateTime(year, month, day, hours, minutes, seconds);
this.Frame.Navigate(typeof(MainPage), chosenDateTime.ToString());
Run Code Online (Sandbox Code Playgroud)
我的MainPage中的OnNavigatedTo方法如下所示:
protected override void OnNavigatedTo(NavigationEventArgs e) {
string parameter = (string)e.Parameter;
if (parameter != "") {
Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings;
roamingSettings.Values["chosenDateTime"] = parameter;
chosenDateTime = Convert.ToDateTime(e.Parameter);
} else {
Windows.Storage.ApplicationDataContainer roamingSettings = Windows.Storage.ApplicationData.Current.RoamingSettings;
if (roamingSettings.Values.ContainsKey("chosenDateTime")) {
chosenDateTime = Convert.ToDateTime(roamingSettings.Values["chosenDateTime"].ToString());
}
if (roamingSettings.Values.ContainsKey("headline")) {
chosenDateTextBlock.Text = roamingSettings.Values["headline"].ToString();
}
}
SetTime();
}
Run Code Online (Sandbox Code Playgroud)
谁能给我一些关于如何解决这个问题的信息?
谢谢.
我非常厌倦检查我的所有参数为null,并在它们出现时抛出ArgumenutNullExceptions.
据我了解,C#4.0通过契约构造实现了一些设计.是否可以指定方法不接受C#4.0中的空参数?
另外,在此期间我可以做些什么(也许是一个属性?)来避免这种单调的检查null和抛出的任务?
假设我有一个方法:
public void SayHello(User user)
{
if (user == null)
throw new ArgumentNullException("user");
Console.Write(string.Format("Hello from {0}", user.Name));
}
Run Code Online (Sandbox Code Playgroud)
很明显,我应该使用如上所示的ArgumentNullException来验证用户不是null.现在我如何验证user.Name不为空?这样做是不错的做法:
if (string.IsNullOrWhiteSpace(user.Name))
throw new ArgumentNullException("user", "Username is empty");
Run Code Online (Sandbox Code Playgroud) c# ×8
.net ×2
arguments ×1
asp.net-mvc ×1
c#-4.0 ×1
comparison ×1
exception ×1
ienumerable ×1
linq ×1
null ×1
page-state ×1
reference ×1
updatemodel ×1
validation ×1
windows-8 ×1