gpt4 book ai didi

c# - 自反类型参数约束 : X where T : X ‒ any simpler alternatives?

转载 作者:IT王子 更新时间:2023-10-29 04:48:56 26 4
gpt4 key购买 nike

我经常通过向其添加自引用(“自反”)类型参数约束来使一个简单的接口(interface)变得更加复杂。例如,我可能会这样:

interface ICloneable
{
ICloneable Clone();
}

class Sheep : ICloneable
{
ICloneable Clone() { … }
} //^^^^^^^^^^

Sheep dolly = new Sheep().Clone() as Sheep;
//^^^^^^^^

进入:

interface ICloneable<TImpl> where TImpl : ICloneable<TImpl>
{
TImpl Clone();
}

class Sheep : ICloneable<Sheep>
{
Sheep Clone() { … }
} //^^^^^

Sheep dolly = new Sheep().Clone();

主要优点:实现类型(例如 Sheep)现在可以引用自身而不是其基类型,从而减少了类型转换的需要(如最后一行代码所示)。

虽然这非常好,但我也注意到这些类型参数约束并不直观,而且在更复杂的场景中往往会变得非常难以理解。*)

问题:有没有人知道另一种 C# 代码模式可以达到相同或类似的效果,但更容易掌握?


*) This code pattern can be unintuitive and hard to understand e.g. in these ways:

  • The declaration X<T> where T : X<T> appears to be recursive, and one might wonder why the compiler doesn't get stuck in an infinite loop, reasoning, "If T is an X<T>, then X<T> is really an X<X<…<T>…>>." (But constraints obviously don't get resolved like that.)

  • For implementers, it might not be obvious what type should be specified in place of TImpl. (The constraint will eventually take care of that.)

  • Once you add more type parameters and subtyping relationships between various generic interfaces to the mix, things get unmanageable fairly quickly.

最佳答案

Main advantage: An implementing type can now refer to itself instead of its base type, reducing the need for type-casting

虽然它可能看起来像是通过引用自身 的类型约束,它强制实现类型做同样的事情,但实际上它不是这样做的。人们使用此模式来尝试表达“此方法的覆盖必须返回覆盖类的类型”形式的模式,但这实际上并不是类型系统表达或强制执行的约束。我在这里举个例子:

https://ericlippert.com/2011/02/02/curiouser-and-curiouser/

While this is very nice, I've also noticed that these type parameter constraints are not intuitive and have the tendency to become really difficult to comprehend in more complex scenarios

是的。我尽量避免这种模式。很难推理。

Does anyone know of another C# code pattern that achieves the same effect or something similar, but in an easier-to-grasp fashion?

不在 C# 中,不。如果您对这类事情感兴趣,您可能会考虑查看 Haskell 类型系统; Haskell 的“高级类型”可以表示这些类型模式。

The declaration X<T> where T : X<T> appears to be recursive, and one might wonder why the compiler doesn't get stuck in an infinite loop, reasoning, "If T is an X<T>, then X<T> is really an X<X<…<T>…>>."

在推理如此简单的关系时,编译器永远不会陷入无限循环。但是,具有逆变的泛型的标称子类型通常是不可判定的。有一些方法可以迫使编译器无限倒退,而 C# 编译器不会检测到这些并在开始无限之旅之前阻止它们。 (但是。我希望在 Roslyn 编译器中添加对此的检测,但我们会看到。)

如果您对此感兴趣,请参阅我关于该主题的文章。您还需要阅读链接到的论文。

https://ericlippert.com/2008/05/07/covariance-and-contravariance-part-11-to-infinity-but-not-beyond/

关于c# - 自反类型参数约束 : X<T> where T : X<T> ‒ any simpler alternatives?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8866071/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com