一个等价于return关键字的表达式

时间:2011-07-02 21:52:48

标签: c#

void Foo()
{
    var xMaybeNull = GetX();
    if (xMabyeNull == null) return; // Some way to get rid of this extra
                                    // sentence without loosing the check
    // do stuff
}

简单的方法就是这样,但编译器需要一个表达式。

void Foo()
{
    List<Disc[,]> xNeverNull = GetX() ?? return;
    // do stuff
}

问题是,有没有办法编写someSortOfReturnExpression(我猜不是)或其他解决方案,可以在一行上找到我想要的内容?

void Foo()
{
    List<Disc[,]> xNeverNull = GetX() ?? someSortOfReturnExpression;
    // do stuff
}

5 个答案:

答案 0 :(得分:8)

第一个选项出了什么问题?

我个人坚持这个选择。可能最终维护代码的其他人可读,常见且易懂。

答案 1 :(得分:1)

不可能。 ??运算符意味着'如果它不为null,则给我第一个参数,否则为第二个参数。您无法将其用于流量控制。

答案 2 :(得分:1)

由于非“功能语法”,这在C#中是不可能实现的。 (请参阅最底部的注释)。虽然条件运算符(?:)可以在一些琐碎的地方使用,但它很快就会遇到限制。并且,正如其他人所指出的那样,结合表达式的合并运算符(??)不支持“其他”情况。因此,C#函数必须使用约定来实现类似的语义。以下讨论了我解决这个问题的方法。

-

除了极少数例外,我不使用函数的早期返回。虽然C#没有“功能语法”,但我仍然发现从函数的开头到函数结尾的代码样式最清晰 - 也就是说,只有最后一个语句 最后一级分支(可能是嵌套的)可以从函数返回,就像条件本身(if/else if/else)是一个表达式(如?:)那样{{ 1}}编辑一个值。 (如果分支太多,则可能表示函数太大。)

在大多数情况下,我会将代码编写如下:

return

由于我一直遵循这种模式,它可以帮助我更好地阅读/理解我的代码和流程。这种方法也避免了“过于棘手”,只需将void Foo() { var xMaybeNull = GetX(); if (xMabyeNull != null) { // Know it's valid to use xMaybeNull in here -- can't be null. // "do stuff" } // xMaybeNull may be null here. So don't put anything here // that requires otherwise. In this case the flow will just "drop off" // so the `return` is completely omitted. } 添加到最后,就可以非常容易地扩展以处理“null case”。保持作业的第一个和分开使代码更简单,并允许使用else,我发现它非常好。

快乐的编码。


我确实推高了条件和早期功能退出的一个案例是在警卫中提出例外 ......

var

......但这是例外的本质。


实际上,可以以类似于SmallTalk的方式使用扩展方法完成。但是,在这种情况下,它只会引入更多的复杂情况。不要让Cleverness Goggles保持太长时间。想象一下:

if (argX == null) throw new ArgumentNullException("argX");

答案 3 :(得分:0)

根据方法的其余部分,空列表是否会对您班级的其余部分产生影响?如果是这样,你可以使用:

List<Disc[,]> xNeverNull = GetX() ?? new List<Disc[,]>();

虽然List类是基于Arrays的,但是它首先用一个小数组初始化,因此可能会有一些内存损失。如果您不必修改列表,或者您不需要索引器,则可以考虑:

IEnumerable<Disc[,]> xNeverNull = GetX() ?? System.Linq.Enumerable.Empty<Disc[,]>();

ICollection<Disc[,]> xNeverNull = GetX() ?? new LinkedList<Disc[,]>();

答案 4 :(得分:0)

你可以试试这个:

void Foo()
{
    List<Disc[,]> xNeverNull;
    if (null != (xNeverNull = GetX())
    {
    // do the stuff here
    }
}