Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 异常的三元运算符?其他选择?_C#_Exception_Exception Handling_Monads_Ternary Operator - Fatal编程技术网

C# 异常的三元运算符?其他选择?

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.

假设我们有一个Person类型的给定对象,并希望将其Name属性存储在局部变量中,同时避免对象为null时可能出现的异常,我们可以这样做:

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" } };