user1017882
user1017882

Reputation:

Generics or just use overloads?

I have 3 classes, all share similar properties. 3 of the properties are named exactly the same across all 3 classes. Rather that write 3 methods (one for each class) is there some way I can utilise generics here?

public static String GetAString(ActivityMedia activityMedia)
{
   return activityMedia.name;
}

public static String GetAString(AuditMedia auditMedia)
{
   return auditMedia.name;
}

public static String GetAString(VehicleMedia vehicleMedia)
{
   return vehicleMedia.name;
}

EDIT: Obviously with the aim of simply passing an object of one of those 3 class types to GetAString()

Upvotes: 3

Views: 174

Answers (10)

sll
sll

Reputation: 62544

  1. introduce interface with a single string Name property
  2. mark all three classes by interface
  3. Now you can assess media Name directly I've no idea why you need a method for this but anyway, you can create extension method for the interface type IMedia
interface IMedia
{
    string Name { get; }
}

class ActivityMedia : IMedia
class AuditMedia : IMedia
class VehicleMedia : IMedia

static class MediaExtensions
{
   public static string GetName(this IMedia instance)
   {
          return instance.Name;
   }
}

Upvotes: 4

Vlad
Vlad

Reputation: 18633

If they are completely unrelated, one option is to use dynamic (if you're on C# 4):

public static String GetAString(dynamic d){
    return d.name;
}

Edit:

If you're not using C# 4.0, you can use reflection:

public static string GetAString(object o)
{
    System.Reflection.PropertyInfo name = o.GetType().GetProperty("name");
    return (string) name.GetValue(o, null);
} 

Upvotes: 3

Abdul Munim
Abdul Munim

Reputation: 19217

It's more logical to implement inheritance here rather than generics.

You can also use Interface but that would make your Name property duplicate on all your ActivityMedia, AuditMedia, VehicleMedia classes.

Consider a base class Media

public class Media
{
    // consider all properties that are common
    // on Media domain
    public string Name { get; set }
}

And inherit ActivityMedia, AuditMedia, VehicleMedia from Media class.

public class ActivityMedia : Media
{
    // other properties on ActivityMedia domain
}

public class AuditMedia : Media
{
    // other properties on AuditMedia domain
}

public class VehicleMedia : Media
{
    // other properties on VehicleMedia domain
}

And now use Media class on your GetAString method

public static String GetAString(Media activityMedia)
{
   return activityMedia.name;
}

public static String GetAString(Media auditMedia)
{
   return auditMedia.name;
}

public static String GetAString(Media vehicleMedia)
{
   return vehicleMedia.name;
}

Upvotes: 2

Paulie Waulie
Paulie Waulie

Reputation: 1690

I would have thought that an interface would be the ideal solutions here:

public interface IMedia
{
    public String Name { get; }
}

and then you could have your static method taking that interface type as it's parameter:

    public static String GetAString(IMedia media)
    {
        return media.Name;
    }

Or all of your media classes could derive from a base type which contains the property you require and pass that into the method instead of the interface.

It's difficult to tell you which is the better option because it depends on the complexity of your application and the inheritance chain already.

This article may be of help

Upvotes: 3

Chris
Chris

Reputation: 3162

If the three classes have a sub set of the same properties your better off implementing a base class instead with the common properties and methods declared in the base class which the three media classes are derived from.

public class ActivityMedia : Media 
{

}

public class Media
{
     public string Name {get;set;}
}

This way the three classes have one set of methods defined in one place making the code much easier to maintain. while giving you the flexibility to put class specific methods in their derived implementation.

Upvotes: 2

David Heffernan
David Heffernan

Reputation: 613311

Generics won't help you here if these classes share no common ancestry. The solution is to arrange that they do share common ancestry by declaring an interface with a name property. Make each class implement that interface and then you can have a single GetAString function.

Upvotes: 2

Russ Cam
Russ Cam

Reputation: 125528

You could do this with an interface

public interface INamedMedia
{
    string Name { get; }
}

then your method becomes

public static String GetAString(INamedMedia media)
{
    return media.Name;
}

and your classes implement INamedMedia

public class Media : INamedMedia
{
    public string Name { get { return "Media"; } }
}

Upvotes: 3

Shadow Wizzard
Shadow Wizzard

Reputation: 66388

This is where inheritance comes to your rescue. Have such base class:

public class Media
{
    public string name { get { return "Media"; } }
}

Then each class will inherit and define its own name:

public class ActivityMedia : Media
{
    public new string name { get { return "Activity Media"; } }
}

And finally:

public static String GetAString(Media media)
{
    return media.name;
}

Edit: as you're stuck with your current design, you can use reflection:

public static String GetAString(object media)
{
    PropertyInfo propName = media.GetType().GetProperty("name");
    if (propName != null)
        return propName.GetValue(media, null);
    return "";
}

Upvotes: 1

Davide Piras
Davide Piras

Reputation: 44605

you do not need generics, you need OOP and inheritance.

Make ActivityMedia, AuditMedia and VehicleMedia all to either implement a base interface like IMedia or derive a basic class like MediaBase

then you write the method GetAString only once which accepts either an IMedia object or a MediaBase object.

another option could be that you override the default ToString method in ActivityMedia, AuditMedia and VehicleMedia so to just return the name property then you will just call ToString without the need of any GetAString method.

Upvotes: 2

Ian
Ian

Reputation: 34509

Another option is to use an interface...

public interface INameable
{
   String Name { get; }
}

public static String GetAString(INameable nameable)
{
   return nameable.Name;
}

Although at this point you probably don't even need the GetAString method?

Upvotes: 3

Related Questions