1

我正在为 .NET 构建一个 HTTP-API 包装器,它有一堆方法可以在对象中设置数据,然后将数据序列化并将其发送到我的服务器。允许使用 6 种数据类型:

  • 细绳
  • 整数
  • 漂浮
  • 双倍的
  • 约会时间

我的数据属性使用泛型:

SetAttribute<T>(string key, T value)

所以只有一种通用的方法来设置数据。由于我无法将数据类型限制为提到的 6 个,因此我使用运行时检查并在使用错误数据类型时抛出异常。

现在解决我的问题:我有两个版本的 SetAttribute,一个接受单个值(T 类型),另一个接受多个值(IEnumerable<T> 类型)。问题是当程序员使用这个包装器并且没有指定类型参数时,运行时会猜测使用哪个方法,例如:

SetAttribute("testkey","thing,anotherthing,athirdthing".Split(','))

这默认为单值方法,T 是 String[],这当然会使我的方法抛出异常,因为 String[] 不是有效类型。如果您指定:

SetAttribute<string>("testkey","thing,anotherThing,aThirdThing".Split(','))

运行时选择正确的方法(多值)并且没有异常被转换,因为 T 是字符串。

我的问题:如何标记我的方法,以便类型参数是强制性的并且必须明确定义?还是我必须在运行时检测到这一点并自己重定向到多方法?

4

4 回答 4

2

给定参数类型,编译器会从您的重载中找到最佳匹配。如果您将您的string[]转换为 anIEnumerable<string>您可能会发现它按预期工作,因为最佳匹配是具有完全这些参数的方法。但是您没有采用 a 的方法string[],因此给定一个作为参数,编译器会做出最好的猜测。

我将有两个单独命名的方法而不是重载,否则很容易遇到这个问题。或者正如@Joachim 建议的那样,有 6 个单独的重载。

于 2012-09-25T10:46:00.100 回答
2

好的,这最初是上面的评论,因为它不一定回答您的原始问题,但建议了另一种方法;

我会说在这种情况下使用公共通用SetAttribute 不一定是一个好主意。

由于类型受到如此严格的限制,您可能应该只编写重载并将错误从运行时移动到编译时。它还允许您IEnumerable<string>使用另外 6 个重载等,并完全消除您遇到的问题。

您始终可以使用私有泛型实现 SetAttribute 并从每个重载中调用它,这将消除一些重复。

它也或多或少地消除了运行时检查的需要,因为类型已经受到编译器的约束。

于 2012-09-25T11:04:04.230 回答
0

一种解决方案是将原始方法分解为 6 ​​个非泛型重载,并为集合添加另一个泛型重载:

void SetAttribute(string key, int value);
void SetAttribute(string key, string value);
// etc

// abd this takes care of collections:
void SetAttribute<T>(string key, IEnumerable<T> value);
于 2012-09-25T10:29:49.263 回答
0

我建议一个更好的解决方案是测试传入的值是否是 IEnumerable 在它失败之后,如果它是这样的话。(我想您已经将 IEnumerable 作为第七种情况处理)。

于 2012-09-25T10:33:21.967 回答