有没有办法使用 C# 4 中新的协/逆变来实现这种类型层次结构?

发布于 2024-11-16 11:15:46 字数 897 浏览 7 评论 0原文

假设我有一个像这样的句柄类:

interface IHasHandle<TObject> {
     IHandle<TObject> Handle { get; }
}

interface IHandle<out TObject> {
     TObject Value { get; }
}

我想使用这个类为我提供层次结构中派生的输出类型。我现在的样子:

interface IAnimal : IHasHandle<IAnimal> { ... }

interface IMammal : IAnimal, IHasHandle<IMammal> { ... }

interface IFeline : IMammal, IHasHandle<IFeline> { ... }

class Tiger : IFeline {
     IHandle<IAnimal> IHasHandle<IAnimal>.Handle { get { ... } }
     IHandle<IMammal> IHasHandle<IMammal>.Handle { get { ... } }
     IHandle<IFeline> IHasHandle<IFeline>.Handle { get { ... } }
     public IHandle<Tiger>   Handle { get { ... } }
}

这意味着当我有一个 IAnimal 时,我总是可以得到 IHandle,当我有 IMammal 时,我可以得到 IHandle 等等。

有没有人对这个结构有任何一般性评论或关于如何避免拥有的想法每种可能的实施?

Suppose I have a handle class like:

interface IHasHandle<TObject> {
     IHandle<TObject> Handle { get; }
}

interface IHandle<out TObject> {
     TObject Value { get; }
}

I would like to the use this class to give me the most derived output type in a hierarchy. What I have now looks like:

interface IAnimal : IHasHandle<IAnimal> { ... }

interface IMammal : IAnimal, IHasHandle<IMammal> { ... }

interface IFeline : IMammal, IHasHandle<IFeline> { ... }

class Tiger : IFeline {
     IHandle<IAnimal> IHasHandle<IAnimal>.Handle { get { ... } }
     IHandle<IMammal> IHasHandle<IMammal>.Handle { get { ... } }
     IHandle<IFeline> IHasHandle<IFeline>.Handle { get { ... } }
     public IHandle<Tiger>   Handle { get { ... } }
}

This means that when I have an IAnimal, I can always get IHandle, when I have IMammal, I can get IHandle, etc.

Does anyone have any general comments on this structure or ideas for how to avoid having every possible implementation?

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

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

发布评论

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

评论(1

琉璃繁缕 2024-11-23 11:15:46

即使在 .NET 4.0 之前,也可以执行以下操作:

interface IAnimal<TSpecies> : IHasHandle<TSpecies> where TSpecies : IAnimal<TSpecies> { ... }

interface IMammal<TSpecies> : IAnimal<TSpecies> where TSpecies : IMammal<TSpecies> { ... }

interface IFeline<TSpecies> : IMammal<TSpecies> where TSpecies : IFeline<TSpecies> { ... }

class Tiger : IFeline<Tiger> {
    IHandle<Tiger> IHasHandle<Tiger>.Handle { get { ... } }
}

当然,这不会阻止您创建一些 class EvilCat : IFeline,但它提供了一种很好的摆脱方法Tiger 中额外不需要的 Handle 实现。如果您在此代码示例中将 IHasHandle 泛型参数声明为 out 1,则您将能够强制转换 Tiger (它实现例如,将 IHasHandle) 转换为 IHasHandle

Even before .NET 4.0 it was possible to do things like:

interface IAnimal<TSpecies> : IHasHandle<TSpecies> where TSpecies : IAnimal<TSpecies> { ... }

interface IMammal<TSpecies> : IAnimal<TSpecies> where TSpecies : IMammal<TSpecies> { ... }

interface IFeline<TSpecies> : IMammal<TSpecies> where TSpecies : IFeline<TSpecies> { ... }

class Tiger : IFeline<Tiger> {
    IHandle<Tiger> IHasHandle<Tiger>.Handle { get { ... } }
}

Of course, this won't prevent you from making some class EvilCat : IFeline<Tiger>, but it provides quite a good way for getting rid of an extra unneeded Handle implementations in Tiger. And if you'll declare IHasHandle generic parameter as out one in this sample of code, you'll be able to cast Tiger (which implements IHasHandle<Tiger>) to IHasHandle<IMammal> for example.

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