Reputation:
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
Reputation: 62544
string Name
propertyIMedia
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
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
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
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
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
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
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
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
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
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