我应该使用哪种退货方式?

und*_*oft 10 c# conventions return-value

这与C#中使用的约定有关.

我有一个方法有两个参数(X和Y坐标).这些坐标表示"图块"可以驻留的位置.如果图块位于这些坐标处,则该方法返回其编号.如果没有磁贴位于这些坐标,我想知道该方法应该如何表现.

我看到三个选择:

  1. 使用例外.每次Method找不到tile时我都会引发异常.但是,由于这种情况并不罕见,因此这个选项是最糟糕的选择.
  2. 用旧式C++方式做,如果没有瓷砖,则返回-1.
  3. 使tile数字成为引用参数,并将方法的返回类型更改为boolean以显示是否存在tile.但这对我来说似乎有点复杂.

所以我该怎么做?

Jay*_*ggs 23

您可以返回null,并在调用代码上检查这一点.

当然你必须使用可空类型:

int? i = YourMethodHere(x, y);
Run Code Online (Sandbox Code Playgroud)


Joe*_*Joe 20

返回-1.

这不仅仅是一个C++约定,它在.NET Framework中也很常见 - 例如像String.IndexOf这样的方法,或者像SelectedIndex这样的属性,用于表示列表的控件.

编辑

只是详细说明你问题中的三个选项(异常,返回-1,输出参数),返回-1是要走的路.例外情况适用于特殊情况,Microsoft编码指南建议尽可能避免使用参数.

在我的视图中返回-1(假设它总是一个无效的值),返回一个可空的int或返回一个Tile对象都是可接受的解决方案,你应该选择与你应用程序的其余部分最一致的那个.我无法想象任何开发人员都会遇到以下任何一点困难:

int tileNumber = GetTile(x,y);
if  (tileNumber != -1)
{
   ... use tileNumber ...
}


int? result = GetTile(x,y);
if (result.HasValue)
{
    int tileNumber = result.Value; 
   ... use tileNumber ...
}


Tile tile = GetTile(x,y);
if (tile != null)
{
   ... use tile ...
}
Run Code Online (Sandbox Code Playgroud)

我不确定我是否理解Peter Ruderman关于使用int"比返回可空类型更有效"的评论.我认为任何差异都可以忽略不计.

  • "Nullables是一个更健全的选择".取决于上下文.最重要的是要与您在应用程序其余部分中使用的约定保持一致. (5认同)
  • 这是唯一的共同点,因为在创建这些方法时不存在nullables - 或者因为共同性的延续(即旧习惯难以摆脱).我相信,Nullables是一个更加理智的选择. (3认同)

Col*_*ett 17

例外是针对特殊情况,因此在已知预期的错误情况下使用异常是"不好的".现在,你更有可能在任何地方都有try-catches来处理这个错误,因为你预计会发生这种错误.

如果您的唯一错误条件(比如-1)与实际值混淆,则使返回值成为参数是可以接受的.如果你有一个负片数,那么这是一个更好的方法.

可以为空的int是参考参数的一种可能替代方法,但是您正在创建具有此参数的对象,因此如果"错误"是常规的,那么您可能会以这种方式比参考参数做更多的工作.正如罗曼在其他地方的评论中所指出的那样,你将会遇到C#与VB的问题,因为可引用的类型为VB提供了太晚,以至于无法提供像C#那样的优秀语法糖.

如果您的图块只能是非负图形,则返回-1是指示错误的可接受且传统的方式.就性能和内存而言,它也是最便宜的.


还需要考虑的是自我记录.使用-1和异常是惯例:您必须编写文档以确保开发人员了解它们.使用int?return或reference参数可以更好地自我描述,并且不需要开发人员知道如何处理错误情况的文档.当然:)你应该总是写文档,就像你每天应该用牙线一样.

  • +1到目前为止最好和最明确的解释. (2认同)
  • Pyran,你正在分裂头发.undsoft*知道*一个未找到的图块将是常见的并且*假设*以宽限期处理丢失的图块.例如,如果坐标超出范围,那么这将是例外.但是,如果这是一个接近用户输入的方法,那么预计通常会出现错误,那么异常将是错误的方法. (2认同)

Dar*_*rio 6

使用可以为空的返回值.

int? GetTile(int x, int y) {
   if (...)
      return SomeValue;
   else
      return null;
}
Run Code Online (Sandbox Code Playgroud)

这是最清晰的解决方案.