Дженерики или просто перегрузки? - PullRequest
3 голосов
/ 24 ноября 2011

У меня есть 3 класса, все они имеют похожие свойства.3 свойства названы одинаково во всех 3 классах.Вместо того, чтобы написать 3 метода (по одному для каждого класса), есть ли способ, как я могу использовать здесь дженерики?

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;
}

РЕДАКТИРОВАТЬ: Очевидно, с целью простой передачи объекта одного из этих 3 типов классов в GetAString()

Ответы [ 10 ]

4 голосов
/ 24 ноября 2011
  1. введение интерфейса с одним string Name свойством
  2. маркировка всех трех классов по интерфейсу
  3. Теперь вы можете напрямую оценивать имя носителя. Я понятия не имею, зачем вам нужен методдля этого, но в любом случае, вы можете создать метод расширения для типа интерфейса 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;
   }
}
3 голосов
/ 24 ноября 2011

Я бы подумал, что интерфейс будет идеальным решением здесь:

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

и тогда ваш статический метод может использовать этот тип интерфейса в качестве параметра:

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

Или все ваши классы мультимедиа могут быть производными от базового типа, который содержит требуемое свойство, и передавать его в метод вместо интерфейса.

Трудно сказать, какой вариант лучше, потому что это уже зависит от сложности вашего приложения и цепочки наследования.

Эта статья может помочь

3 голосов
/ 24 ноября 2011

Вы можете сделать это с помощью интерфейса

public interface INamedMedia
{
    string Name { get; }
}

тогда ваш метод становится

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

и ваши классы реализуют INamedMedia

public class Media : INamedMedia
{
    public string Name { get { return "Media"; } }
}
3 голосов
/ 24 ноября 2011

Другой вариант - использовать интерфейс ...

public interface INameable
{
   String Name { get; }
}

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

Хотя на данный момент вам, вероятно, даже не нужен метод GetAString?

3 голосов
/ 24 ноября 2011

Если они совершенно не связаны, одним из вариантов является использование dynamic (если вы на C # 4):

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

Edit:

Если вы не используете C # 4.0, вы можете использовать отражение:

public static string GetAString(object o)
{
    System.Reflection.PropertyInfo name = o.GetType().GetProperty("name");
    return (string) name.GetValue(o, null);
} 
2 голосов
/ 24 ноября 2011

Более логично реализовать здесь наследование, а не генерики.

Вы также можете использовать Interface, но это сделает ваше свойство Name дублированным на всех ваших ActivityMedia, AuditMedia, VehicleMedia классах.

Рассмотрим базовый класс Media

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

И наследуют ActivityMedia, AuditMedia, VehicleMedia от Media класса.

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
}

А теперь используйте Media класс в вашем GetAString методе

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;
}
2 голосов
/ 24 ноября 2011

Если у трех классов есть подмножество одинаковых свойств, вам лучше реализовать базовый класс вместо общих свойств и методов, объявленных в базовом классе, из которого получены три класса мультимедиа.

public class ActivityMedia : Media 
{

}

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

Таким образом, три класса имеют один набор методов, определенных в одном месте, что значительно упрощает поддержку кода. в то же время давая вам гибкость, чтобы поместить специфичные для класса методы в их производную реализацию.

2 голосов
/ 24 ноября 2011

Дженерики здесь не помогут, если у этих классов нет общих предков. Решение состоит в том, чтобы договориться, что они имеют общую родословную, объявив интерфейс со свойством name. Сделайте так, чтобы каждый класс реализовывал этот интерфейс, и тогда у вас будет одна GetAString функция.

2 голосов
/ 24 ноября 2011

вам не нужны дженерики, вам нужны ООП и наследование.

Создайте ActivityMedia, AuditMedia и VehicleMedia все для реализации базового интерфейса, например IMedia, или получения базового класса, напримерMediaBase

затем вы пишете метод GetAString только один раз, который принимает либо IMedia объект, либо MediaBase объект.

другой вариант может заключаться в том, что вы переопределяете значение по умолчанию ToString метод в ActivityMedia, AuditMedia и VehicleMedia, поэтому, чтобы просто вернуть свойство name, вы просто вызовете ToString без необходимости использования какого-либо GetAString метода.

1 голос
/ 24 ноября 2011

Здесь на помощь приходит наследство.Иметь такой базовый класс:

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

Тогда каждый класс будет наследовать и определять свое собственное имя:

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

И, наконец:

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

РедактироватьВы застряли с вашим текущим дизайном, вы можете использовать отражение:

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