2

First of all, it was difficult to find a proper title for my question... sorry in advance for this.

I am facing an issue with C# .NET. I'll try to simplify it with a temporary example.

I have three classes:

book movie_dvd game_dvd

each of them have the same base properties such: id and name. We can however suppose they have other different properties and different methods to be the same class. They can of course be children of a parent class to make it better.

Then I create List of each of these classes to define my collection of books, movies and games. Their id property is of course matched with the key of the List, and as I insert each item in the List I give them an appropriate name (their title).

I have a main winForm with 3 buttons: “Show Books Collection”, “Show Movies Collection” and “Show Games Collection”. The user can click one of them, and then another window appear and show the passed collection inside a ListBox (or whatever).

Now here's my problem.

Right now I'm creating three separate (but almost identical) WinForms to display the content of each collection (books, movies, games), which I think is greatly overdoing things. What I would really like to do is create a single window to display the content of any of these collections. The problem is that if I pass a book object/class inside the parameters of the new winForm, on the other side it expects to be a book object.

How can I use a single Winform to display the title of each of these differnt objects without duplicating the WinForm code over and over?

chtenb
  • 14,924
  • 14
  • 78
  • 116
TheScholar
  • 2,527
  • 5
  • 23
  • 25

2 Answers2

6

If your form displays the 'common stuff' between the 3 classes - ID, Title, reviews, etc - than you have two choices:

  1. Design a base class that contains these common attributes that each of the other classes can derive from, each possibly overloading and/or modifying the functionality of the base. The form accepts lists of the base class.

  2. Design an interface that defines the base properties and have each of your classes implement it. The form accepts lists of objects that implement the interface.

Both of these solutions are somewhat future-proof too - you can define a 4th kind of thing that inherits or implements accordingly and your form will be none the wiser!

I like #2 better becuase it is great for testing - you can mock up any class that implements your interface and pass it to your form to test it out. No need to test with known-book/dvd/game data!

I'm not a fan of the casting-solutions becuase they're brittle, and tough to extend.

n8wrl
  • 19,439
  • 4
  • 63
  • 103
  • I like this answer. If you're going to implement it this way be sure to check this out: http://stackoverflow.com/questions/56867/interface-vs-base-class – Ian R. O'Brien Dec 07 '12 at 21:34
4

If each of these objects will have the same properties (e.g. Title) then you create a base class with those properties. You could then create more specific properties in the derived classes.

public abstract class MediaBase
{
    public String Title { get; set; }
    public Int32 Id { get; set; }
}

public sealed class Book : MediaBase
{
    public String Author { get; set; }
    public Int32 Pages { get; set; }
}

public sealed class MovieDvd : MediaBase
{
    public String Director { get; set; }
    public Int32 Length { get; set; }
}

public sealed class GameDvd : MediaBase
{
    public Int32 NumberOfPlayers { get; set; }
}

Or you could pass the parameters as objects and then cast them back into their actual type.

if (parameter is book)
{
    book theBook = ((book)parameter);
}
else if (parameter is movie_dvd)
{
    movie_dvd movieDvd = ((movie_dvd)parameter);
}
else if (parameter is game_dvd)
{
    game_dvd gameDvd = ((game_dvd)parameter);
}
Ian R. O'Brien
  • 6,682
  • 9
  • 45
  • 73