【问题标题】:Tuples vs. custom struct for async version of a method with ref/out parameter带有 ref/out 参数的方法的异步版本的元组与自定义结构
【发布时间】:2013-03-16 04:02:09
【问题描述】:

考虑使用具有 outref 参数的方法的 C# API,例如:

Person FindPerson(string name, out int searchTime);

我们不要注意 out 和 ref 参数通常是一种设计味道,假设这是一个遗留 API,我们无法更改其现有方法的签名。但我们需要扩展 API 以支持异步执行(Windows Phone、WinRT 应用程序)。这是一个无法编译的实现:

Task<Person> FindPersonAsync(string name, out int searchTime)
{
    return Task.Factory.StartNew(() => this.FindPersonAsync(name, out searchTime));
}

由于 out 参数,此实现无法编译。所以我们必须更改 API 签名。一种方法是将结果从 task-of-person 更改为 task-of-tuple-of-person-and-int,即委托实现将返回 Person 和 int 的元组。第二种选择是定义一个自定义结构。

元组优势:使用元组提供了一种非常正式的方法,可用于轻松定义任何 API 的异步版本。可预测的实现(未定义新名称)。使用自定义结构需要为每个此类案例发明​​新的类型和成员。

自定义结构的优势:使用元组的客户端代码需要使用 Item1Item2 名称来引用元组元素。这很模糊。

我没有找到任何建议,暂时决定使用元组。但我想知道在使用异步支持扩展 API 时是否有处理此类方法的推荐做法。

【问题讨论】:

  • 这是非常主观的。他们都工作,都不是完美的,运行时不在乎。选择你的毒药。请检查this meta question
  • 如果您使用TimeSpan 而不是int 作为searchTime 结果,您的代码可能会更清晰。
  • 同意 TimeSpan 可能是新 API 的更好选择。但我正在处理现有的版本,并希望尽可能接近原始版本。

标签: c# async-await c#-5.0 out ref


【解决方案1】:

我不知道关于此事的任何最佳做法或建议;但根据我自己的经验,Tuple 使代码变得丑陋且毫无意义 - 当您看到 Item1 时,这意味着什么?

我总是使用自定义类并遵守一些约定:

  • 自定义类的名称以Result 结尾,如FindPersonResult
  • 将类设计为 POCO,在构造函数中没有特殊逻辑。当您使用系统的其他部分和其他 API(尤其是在序列化和反序列化时)时,这可以防止任何意外。
  • 始终将集合字段/属性(数组、列表等)的初始值设置为非空值。这在很多情况下也有帮助。

请记住,这些只是我在这件事上的个人经历,对我来说非常有效。

【讨论】:

  • 嗨 Kaveh,我同意你关于基于元组的名称丑陋的观点,这绝对是在不同的替代方案之间进行选择时的一个重要考虑因素。
猜你喜欢
  • 2021-07-03
  • 2013-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-05
相关资源
最近更新 更多