How do you work with a variable that can be of several types?

I often associate objects with parents using:

Video parent; 

Sometimes I have objects that can be children of different types of objects, so 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 can I work with a variable that can be an instance of different types?

Edit: Of course, if video and audio are inherited from the same base class (e.g. Media), I could do this:

  Media parent; 

But what if parents do not inherit from the same base class?

+4
source share
4 answers

I assume the types in your question are sealed. In this case, I would just use an object parent and use as on the output. (Using as may have a higher performance impact than checking a flag, but ... not a problem in anything I did, and it can also be used in null protection.)

 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 stupid C # way to write a one-time pattern matching on an unlimited discriminatory union (an object is a union of every other type in C # :-)

+9
source

Well, as a rule, an interface that provides all the functionality is suitable, and this may be your type. Otherwise (or also) you can consider generics:

Same:

 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 } 
+7
source

Try to make a difference ... does that make 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(); } 
+3
source

If there is no Media base class from which they are derived, but there are common functions that can apply equally well to audio or video content, then you can create a new MediaContainer class that accepts the content of an object and performs operations differently depending on specific type of content. This makes encapsulating the ugly "switch" functionality in the shell so you can write code that depends on the media container without worrying about the specific medium that it contains, or how it handles the ugly work of delegating calls.

+1
source

Source: https://habr.com/ru/post/1316481/


All Articles