【问题标题】:How do you work with a variable that can be of multiple types?您如何处理可以是多种类型的变量?
【发布时间】:2023-03-15 14:31:01
【问题描述】:

我经常使用以下方法将对象链接到它们的父对象:

 Video parent;

有时我的对象可以是不同对象类型的子对象,我也是:

 int parentType;
 Video parentVideo; // if parent == VIDEO then this will be used
 Audio parentAudio; // if parent == AUDIO then this will be used

有没有更好的方法? 如何使用可以是不同类型实例的变量?

编辑:当然,如果 Video 和 Audio 继承自同一个基类(例如 Media),我可以这样做:

 Media parent;

但是如果父母不是从同一个基类继承呢?

【问题讨论】:

  • 你能提供更多细节吗?什么样的对象可以有一个音频或视频“父级”?你对父母进行了哪些操作——Object parent 就足够了吗?
  • 是的,正如丝绸所描述的,您正试图以错误的方式使用继承。音频不是视频,反之亦然。但是,它们都是媒体类型,并且都包含一些数据。那是他们应该共享的界面。
  • "但是如果父母没有从同一个基类继承呢?"这个问题以虚假为前提。两种类类型总是从同一个基类继承(直接或间接):System.Object。
  • @Eric:那条评论到底有什么用?考虑到它的迂腐程度,它也是错误的,System.Object 不是从 System.Object 继承的。我认为像你这样的人实际上可以提供有用的反馈。
  • 这是有用的反馈,因为它指出发帖人忘记了一个重要的点:变量可以被设为对象类型。那肯定能解决问题。

标签: c# types strong-typing base-class


【解决方案1】:

我假设您问题中的类型是密封的。在这种情况下,我只会使用object parent 并在退出时使用as。 (使用as 可以比检查标志对性能产生更高的影响,但是......我所做的任何事情都不是问题,它也可以很好地用于null-guard。)

Video video = null;
if ((video = parent as Video) != null) {
  // know we have a (non-null) Video object here, yay!
} else if (...) {
  // maybe there is the Audio here
}

上面实际上只是一种愚蠢的 C# 方式,在无约束的可区分联合上编写一次性模式匹配(对象是 C# 中所有其他类型的联合:-)

【讨论】:

  • +1:我已经多次这样做了。记住基地Object 总是很重要的!
【解决方案2】:

嗯,通常一个公开所有功能的接口是合适的,这可以是你的类型。否则(或同样)你可以考虑泛型:

像这样:

class Something<TMediaType>
    where TMediaType : IMedia // use this statement to limit the types. It
                              // is not required, if not specified it can be 
                              // of any type
{
    TMediaType data;

    // other such things
}

【讨论】:

    【解决方案3】:

    试着扭转局面……这样更有意义吗?

    interface IMedia 
    {
      void Play();
      void Stop();
    }
    
    class Video : IMedia
    {
      public Audio Audio; /// aka child
    
      public void Play() { }
      public void Stop() { }
    }
    
    class Audio : IMedia
    {
      public Video Video; /// aka parent...questionable unless Audio 
                          /// always has a parent Video
    
      public void Play() { }
      public void Stop() { }
    }
    
    private void PlayAnyMedia(IMedia media) /// Write against an interface
    {
      media.Play();
    }
    

    【讨论】:

      【解决方案4】:

      如果没有派生它们的基类 Media,但有可以同样适用于音频或视频内容的通用功能,那么您可以创建一个新的 MediaContainer 类,该类接受对象内容并根据不同的情况执行不同的操作关于特定类型的内容。这样做的目的是将丑陋的“切换”功能封装到一个包装器中,这样您就可以编写依赖于 MediaContainer 的代码,而不必担心它包含的特定媒体或它如何处理委派调用的丑陋工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-05
        • 2020-07-15
        • 1970-01-01
        • 1970-01-01
        • 2018-05-27
        • 1970-01-01
        • 1970-01-01
        • 2021-11-23
        相关资源
        最近更新 更多