RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 586014
Accepted
eastwing
eastwing
Asked:2020-11-02 23:20:56 +0000 UTC2020-11-02 23:20:56 +0000 UTC 2020-11-02 23:20:56 +0000 UTC

“分形”界面没有意义?

  • 772

在消除我知识上的灾难性差距的过程中,我勾画了一个特定的类,像这样(我没有在列表中包括构造函数和方法,无论如何这个问题都很难理解):

public class SomeFractal
{
        public int Generation;
        public SomeFractal Parent { get; private set; }
        public SomeFractal Root
        {
            get
            {
                if (Generation == 0) return this;
                else return Parent.Root;
            }
        }

    List<Fractal> Children {get;}
}

这样做是为了计算递归算法,但我不是在谈论那个。

出现了描述几个细节不同的“分形”类并实现单个接口的想法,让它成为 IFractal。该界面应包含主要属性(父、根、子分支)。

大多数属性自然会返回描述它们的类的对象(我们有一个分形,还记得吗?),所以如果我希望它们在接口中被描述,它必须是协变的。结果是这样的:

interface IFractal <out T> where T : IFractal<T>
{
    T Root { get; }
    T Parent { get; }

    IEnumerable<T> Children { get; }
}

实际上,没有问题——接口当然是由上述类实现的:

class SomeFractal : IFractal<SomeFractal>

如果我想在其他地方使用类型变量IFractal<T>来从特定的实现类中抽象出来,问题就会出现。毕竟,我必须指定参数 T,它只能是实现了 IFractal 的类——也就是说,没有获得任何抽象,在这种情况下它与使用类本身是一样的。

有没有办法绕过这个限制?也许我在协方差方面失败了?

请不要讨论实际应用的可行性,这纯粹是出于教育目的的理论化。

更新

我将用一个例子来解释非泛型

interface IFractal 
 {
     IFractal Root { get; }
     IEnumerable<IFractal> Children { get; }
 }


 class Fractal : IFractal 
 {
     public IFractal Root { get {
             if (parent == null) return this;
             else return parent.Root;
         } }
     public IEnumerable<IFractal> Children { get; }
     private Fractal parent;

     private string prettyCoolField;

     public string GetRootField() {
         return Root.prettyCoolField;
     }
 }

GetRootField()它不会工作,因为它IFractal没有 field prettyCoolField。返回(Fractal)Root.prettyCoolField;也不起作用。还是我错误地转换了类型?

c#
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Pavel Mayorov
    2020-11-03T00:09:58Z2020-11-03T00:09:58Z

    通常他们是这样做的:

    interface IFractal<T> where T : IFractal<T>
    

    这将允许在不知道 T 的具体类型的情况下遍历“导航”属性。

    • 7
  2. Best Answer
    VladD
    2020-11-03T21:14:27Z2020-11-03T21:14:27Z

    如果你一方面想要一个表示树、树的元素的类,另一方面想要一个不依赖于类本身的读取接口,那么你需要将数据和接口的实现。

    这没有问题,因为 getter-only 属性IEnumerable<T>已经是类型 covariant T。结果,我们得到了通常的界面:

    interface IFractal
    {
        IFractal Root { get; }
        IFractal Parent { get; }
        IEnumerable<IFractal> Children { get; }
    }
    

    及其实施:

    class Fractal : IFractal
    {
        public Fractal Root { get; }
        public Fractal Parent { get; }
        public IEnumerable<Fractal> Children { get; private set; }
    
        IFractal IFractal.Root => Root;
        IFractal IFractal.Parent => Parent;
        IEnumerable<IFractal> IFractal.Children => Children;
    }
    
    • 3

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    如何停止编写糟糕的代码?

    • 3 个回答
  • Marko Smith

    onCreateView 方法重构

    • 1 个回答
  • Marko Smith

    通用还是非通用

    • 2 个回答
  • Marko Smith

    如何访问 jQuery 中的列

    • 1 个回答
  • Marko Smith

    *.tga 文件的组重命名(3620 个)

    • 1 个回答
  • Marko Smith

    内存分配列表C#

    • 1 个回答
  • Marko Smith

    常规赛适度贪婪

    • 1 个回答
  • Marko Smith

    如何制作自己的自动完成/自动更正?

    • 1 个回答
  • Marko Smith

    选择斐波那契数列

    • 2 个回答
  • Marko Smith

    所有 API 版本中的通用权限代码

    • 2 个回答
  • Martin Hope
    jfs *(星号)和 ** 双星号在 Python 中是什么意思? 2020-11-23 05:07:40 +0000 UTC
  • Martin Hope
    hwak 哪个孩子调用了父母的静态方法?还是不可能完成的任务? 2020-11-18 16:30:55 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    user207618 Codegolf——组合选择算法的实现 2020-10-23 18:46:29 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    Arch ArrayList 与 LinkedList 的区别? 2020-09-20 02:42:49 +0000 UTC
  • Martin Hope
    iluxa1810 哪个更正确使用:if () 或 try-catch? 2020-08-23 18:56:13 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5