通用约束是否应该优先于使用接口作为参数类型?

发布于 2024-09-14 19:07:20 字数 699 浏览 11 评论 0原文

考虑这个简单的函数:

public static bool IsPositive(IComparable<int> value)
{
    return value.CompareTo(0) > 0;
}

现在,如果我将一个 int 传递给这个方法,它就会被装箱。因此,将上述方法定义如下不是更好吗?

public static bool IsPositive<T>(T value) where T : IComparable<int>
{
    return value.CompareTo(0) > 0;
}

以这种方式使用通用约束,我可以实现与上面的代码完全相同的功能,还有一个好处是不需要装箱(因为对 IsPositive 的调用接受类型的参数int)。

上面的示例代码显然毫无意义。但我更广泛的问题是:用后一种方式定义方法(使用泛型约束而不是具有某种接口类型的参数)是否总是有意义,以避免潜在的潜在问题值类型装箱?

我怀疑答案可能是“是的,但它需要更多的输入,并且在许多情况下遇到值类型的可能性很小,例如当方法接受一些 IEnumerable< ;T>。”但我想知道这些方法之间是否存在目前我无法理解的更大差异。

Consider this trivial function:

public static bool IsPositive(IComparable<int> value)
{
    return value.CompareTo(0) > 0;
}

Now, if I pass an int to this method, it gets boxed. Wouldn't it therefore be better to define the above method as follows?

public static bool IsPositive<T>(T value) where T : IComparable<int>
{
    return value.CompareTo(0) > 0;
}

Using a generic constraint in this way, I can achieve exactly the same functionality as the code above, with the added benefit that no boxing is necessary (since a call to IsPositive<int> accepts a parameter of type int).

The example code above is clearly quite pointless. But my broader question is: wouldn't it always make sense to define methods in the latter way (using a generic constraint rather than having a parameter of some interface type), to avoid the potential boxing of value types?

I suspect that the answer is likely to be "yes, but it requires more typing and in many cases encountering a value type will be very unlikely, such as when a method accepts some IEnumerable<T>." But I'm wondering if there's a greater difference between these approaches that is escaping me at the moment.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

謌踐踏愛綪 2024-09-21 19:07:20

一个问题是通用约束实际上并不是签名的一部分。如果你有……

static T Method<T>(T value) where T : ICompareable<int>

static T Method<T>(T value) where T : IEnumerable<int>

……编译器将无法知道哪个是哪个。

并调用 Eric Lippert...

One issue would be with the fact that the generic constrain isn't really part of the signature. If you have ...

static T Method<T>(T value) where T : ICompareable<int>

... and ...

static T Method<T>(T value) where T : IEnumerable<int>

... the compiler wouldn't have a way to know which is which.

And to invoke Eric Lippert...

谎言月老 2024-09-21 19:07:20

对于关于在参数传递后调用该方法是否会引发装箱的问题,评论中存在一些混乱。

当您在类型为带有约束的类型参数的表达式上调用虚拟方法时,C# 编译器会发出 constrained.callvirt 指令。正如人们所希望的那样,这样做是正确的。拳击只有在绝对必要时才会发生。

有关受约束虚拟调用的精确装箱语义的详细信息,请阅读文档:

http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.constrained.aspx

There was some confusion in the comments to the question regarding whether or not the call to the method induces a boxing after the argument is passed.

When you make a call to a virtual method on an expression whose type is a type parameter with a constraint on it, the C# compiler emits a constrained.callvirt instruction. As one would hope, this does the right thing; the boxing only happens when absolutely necessary.

For details regarding the precise boxing semantics of constrained virtual calls, read the documentation:

http://msdn.microsoft.com/en-us/library/system.reflection.emit.opcodes.constrained.aspx

能否归途做我良人 2024-09-21 19:07:20

另一个问题是,当泛型约束位于参数化类型的泛型类型参数上时,例如,

static bool AreAllTheSame<T>(IEnumerable<T> something)
  where T : IEquatable<T>

它并不总是能够以这种方式转换泛型类型参数,除非您引入像这样的第二个类型参数:

static bool AreAllTheSame<S, T>(S something)
  where S : IEnumerable<T>
  where T : IEquatable<T>

这看起来不正确。

Another issue would be when the generic constraint is on a parameterized type's generic type parameters, such as

static bool AreAllTheSame<T>(IEnumerable<T> something)
  where T : IEquatable<T>

It is not always possible to convert the generic type parameter this way, unless you introduce a second type parameter like this:

static bool AreAllTheSame<S, T>(S something)
  where S : IEnumerable<T>
  where T : IEquatable<T>

That just doesn't look right.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文