C# 异常的三元运算符?其他选择?
假设我们有一个Person类型的给定对象,并希望将其Name属性存储在局部变量中,同时避免对象为null时可能出现的异常,我们可以这样做:C# 异常的三元运算符?其他选择?,c#,exception,exception-handling,monads,ternary-operator,C#,Exception,Exception Handling,Monads,Ternary Operator,假设我们有一个Person类型的给定对象,并希望将其Name属性存储在局部变量中,同时避免对象为null时可能出现的异常,我们可以这样做: string personName = null; if (person != null) { personName = person.Name; } 但是,必须在if语句范围之外声明变量并将其初始化为默认值有点麻烦。相反,我们可以使用条件三元运算符这样写: string personName = person != null ? person.
string personName = null;
if (person != null)
{
personName = person.Name;
}
但是,必须在if语句范围之外声明变量并将其初始化为默认值有点麻烦。相反,我们可以使用条件三元运算符这样写:
string personName = person != null ? person.Name : null;
处理try-catch语句时也存在同样的问题。假设我们试图找到一个TcpClient的远程地址。我们可以这样做:
string remoteAddress = null;
try
{
remoteAddress = tcpClient.Client.RemoteEndPoint.ToString();
}
catch (SocketException e)
{
Console.WriteLine(e.Message);
return;
}
然而,据我所知,没有为简化这样的事情定义操作符,考虑到可能的复杂性,我认为这是有充分理由的。我想知道,有没有办法让这类事情更简洁?也许一个涉及单子的解决方案会起作用,或者这个代码应该保持原样。有一个我曾经成功使用过的概念。也许这对你也有帮助。引述:
在面向对象的计算机编程中,空对象是一个对象
具有定义的中性(“空”)行为
换句话说,不是返回null
而是返回一个定义良好的对象,该对象充当“null对象”,因此访问它不会引发异常
另外,有关更多示例,请参见此处:
这适用于“正常”构建的对象,如:
但是可以有个人
和地址
空
。我将在同一页面中添加一个Result
扩展方法,如果“primary”值为null
,它将返回一个默认值
在第页(这是我指向另一页的那一页),它首先在一个人的愿望列表中,他称之为
Null-Safe解除引用
我个人的猜测是,这样的操作符不适用于例外情况,因为它可能会鼓励坏的编码习惯。回顾以下最佳实践指南:
TryParse
这样的方法帮助很大),除了应用程序的顶级UI级别,您可以捕获并记录所有内容
在您的示例中,如果TCP连接断开,算法通常无法继续,那么为什么不让套接字异常冒泡到UI层,在那里它被捕获并向用户显示一条有用的消息(“连接丢失,请检查您的Internet连接。{exception Details}”),与其只是返回并静默地将某些内容记录到控制台,让用户纳闷为什么他的操作没有完成?像TCP连接这样的东西通常表示一种情况,即抛出可能在某个地方捕获和处理的异常是合适的,因为失败的代码可能在块或方法内,而处理异常的代码可能在块或方法外。使用异常比“if(!TryReadOneByte(ref commandLength))break;if(!TryReadNBytes(commandLength,dat))break;”等要干净得多。连接故障应该中止当前操作,但在冒泡到调用方之前可能会导致一次或多次重试(可能在不同的地址)。
public static TResult With<TInput, TResult>(this TInput o,
Func<TInput, TResult> evaluator)
where TResult : class where TInput : class
{
if (o == null) return null;
return evaluator(o);
}
string postCode = this.With(x => person)
.With(x => x.Address)
.With(x => x.PostCode);
var person = new { Address = new { PostCode = "12345" } };