泛型或者只使用重载

本文关键字:重载 或者 泛型 | 更新日期: 2023-09-27 18:15:51

我有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()

泛型或者只使用重载

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

另一个选择是使用一个接口…

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

虽然在这一点上,你可能甚至不需要GetAString方法?

你可以用一个接口

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

我本以为界面是理想的解决方案:

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

然后你可以让你的静态方法接受这个接口类型作为参数:

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

或者你所有的媒体类都可以从包含你需要的属性的基类型派生,并将其传递给方法而不是接口。

很难告诉你哪个是更好的选择,因为它取决于你的应用程序和继承链的复杂性。

这篇文章可能会有所帮助

如果它们完全不相关,一个选择是使用dynamic(如果您使用c# 4):

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

如果你没有使用c# 4.0,你可以使用反射:

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

你不需要泛型,你需要OOP和继承。

使ActivityMedia, AuditMediaVehicleMedia都实现像IMedia这样的基接口或派生像MediaBase这样的基本类

那么你只写一次方法GetAString,它接受一个IMedia对象或一个MediaBase对象。

另一个选择是,你可以覆盖默认的ToString方法在ActivityMedia, AuditMediaVehicleMedia,所以只是返回名称属性,然后你将只调用ToString,而不需要任何GetAString方法。

如果这些类没有共同的祖先,泛型在这里就帮不上忙。解决方案是通过声明带有name属性的接口来安排它们共享共同的祖先。让每个类实现这个接口,然后你就可以有一个单独的GetAString函数。

如果这三个类有相同属性的子集,你最好实现一个基类,而不是在基类中声明的共同属性和方法,这三个媒体类都是从基类中派生出来的。

public class ActivityMedia : Media 
{
}
public class Media
{
     public string Name {get;set;}
}
这样,三个类在一个地方定义了一组方法,使代码更容易维护。

在这里实现继承比实现泛型更合乎逻辑。

您也可以使用Interface,但这会使您的Name属性在所有ActivityMedia, AuditMedia, VehicleMedia类上复制。

考虑一个基类Media

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

Media类继承ActivityMedia, AuditMedia, VehicleMedia

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
}

现在在GetAString方法上使用Media

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

这就是继承可以帮助您的地方。有这样的基类:

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