【发布时间】:2011-11-08 14:29:14
【问题描述】:
如何确保某个类的某个实例永远不会为空?有人告诉我使用 Debug.Assert() 但这样做,我只会确保代码在调试模式下工作,而我也想确保发布时的 is-never-null 条件。
例如,过去我写的代码如下:
public string MyString
{
get
{
if(instance1.property1.Equals("bla"))
{
return bla;
}
}
}
但如果 instance1 为空,则会引发异常。我想避免在将来犯这样的错误并产生这样的异常。
谢谢,
请参阅下面的具体示例来说明问题:
我有一种方法可以根据服务器的响应对用户进行身份验证。方法是这样的:
/// <summary>
/// attempts authentication for current user
/// </summary>
/// <returns></returns>
public AuthResult CheckUser()
{
WebRequest request = WebRequest.Create(GetServerURI);
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
string postdata = "data=" + HttpUtility.UrlEncode(SerializeAuth());
byte[] arr = Utils.AppDefaultEncoding.GetBytes(postdata);
request.ContentLength = arr.Length;
request.Timeout = Convert.ToInt32(TimeUtils.GetMiliseconds(10, TimeUtils.TimeSelect.Seconds));
Stream strToWrite = request.GetRequestStream();
strToWrite.Write(arr, 0, arr.Length);
WebResponse response = request.GetResponse();
using (Stream dataFromResponse = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(dataFromResponse))
{
string readObj = reader.ReadToEnd();
return DeserializeAuth(readObj);
}
}
}
调用这个方法,我使用
_authenticationResult = authObj.CheckUser();
我也有这个属性,等等
public ResultType AuthResult
{
get
{
if (_authenticationResult.auth == "1")
return ResultType.Success;
if (_authenticationResult.auth == "0")
return ResultType.FailAccountExpired;
if (_authenticationResult.auth == "-1")
return ResultType.FailWrongUsernameOrPassword;
if (_authenticationResult.auth == "-2")
return ResultType.Banned;
return ResultType.NoAuthDone;
}
}
public enum ResultType { Success, FailWrongUsernameOrPassword, FailAccountExpired, NoAuthDone, Banned }
发生的事情是 _authenticationResult 曾经为 null,并且属性 AuthResult 在尝试“null.auth”时抛出了一个 nullref。如何确保(可能在 CheckUser() 方法中)它永远不会返回 null。
当我调试应用程序时,它从未发生过。但是在生产中,当服务器超时时,该方法有时会返回 null。
谢谢,
【问题讨论】:
-
该代码实际上不起作用-您需要始终从
getAFAIK 返回一些内容...当instance1为null时,在发布模式下应该发生什么? -
谢谢 - 这只是一些伪代码。通常我也会在 if 块之后用第二次返回来编写这些属性。在发布模式下,如果 instance1 为 null,那么我会得到一个 nullref 异常。我相信我所做的是糟糕的编码实践,也许还有更优雅的事情要做。
-
@unholysampler 是的...我的问题不是例如当
instance1是null时会发生什么,而是应该在这种情况下发生什么?一个特定的例外? -
调试和发布有什么区别?正常情况下,
assert在调试期间处于开启状态,在发布版本中处于关闭状态。 -
看看你发布的代码示例,我认为这样做的优雅方法是重构你的类(也许通过将它分成两个类,或者我们可以讨论的其他方法),这样绝对没有调用者在 _authenticationResult = authObj.CheckUser(); 行之前调用 AuthResult 的方式被执行
标签: c# coding-style exception-safety