How do you work with a variable that can be of multiple types?
Asked Answered
A

4

5

I frequently link objects to their parents using:

 Video parent;

Sometimes I have objects that can be children of different object types, so do I:

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

Is there a better way? How do I work with a variable that can be an instance of different types?

Edit: Of course, if Video and Audio inherit from the same baseclass (eg. Media) I could do this:

 Media parent;

But what if the parents do not inherit from the same baseclass?

Aorist answered 21/7, 2010 at 23:11 Comment(5)
Can you give more detail? What kind of object can have an audio OR video "parent"? What operations do you perform on the parents--would Object parent suffice?Camarata
Yes, as silky has described, you are trying to use inheritance in the wrong way. Audio is not Video and vice versa. However, they are both types of media, and they both consist of some data. That is the interface they should share.Stephi
"But what if the parents do not inherit from the same baseclass?" The question presupposes a falsehood. Two class types always inherit (directly or indirectly) from the same base class: System.Object.Anaclitic
@Eric: Exactly how is that comment useful? Given it's level of pedanticness, it's also immediately wrong, System.Object doesn't inherit from System.Object. I would think that someone of your stature could actually provide useful feedback.Maximo
It is useful feedback because it points out that the poster has forgotten an important point: the variable could be made to be of type object. That would certainly solve the problem.Anaclitic
C
8

I am assuming that the types in your question are sealed. In which case I would just use object parent and use as on the way out. (Using as can have a higher performance impact than checking a flag, but... not a concern in anything I have done and it can also be nicely used in a 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
}

The above is actually just a silly C# way of writing a one-off-pattern-match on an unconstrained discriminated union (object is the union of every other type in C# :-)

Cervine answered 21/7, 2010 at 23:18 Comment(1)
+1: I have done this on several occasions. Always important to remember the base Object!Gladygladys
M
7

Well, generally an interface which exposes all functionality is appropriate, and this can be your type. Otherwise (or as well as) you may consider generics:

Like so:

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
}
Maximo answered 21/7, 2010 at 23:14 Comment(0)
N
4

Try turning things around....does this make more sense ?

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();
}
Ne answered 21/7, 2010 at 23:46 Comment(0)
C
1

If there is not a base class Media from which they derive, but there is common functionality that could apply equally well to Audio or Video content, then you could create a new MediaContainer class that accepts an Object Content and performs operations differently depending on the specific type of Content. What this does is encapsulate the ugly 'switching' functionality into a wrapper so that you can write code that depends on a MediaContainer without worrying about the specific Media it contains or how it handles the ugly work of delegating the calls.

Childish answered 21/7, 2010 at 23:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.