通用方法 - 寻求设计建议

时间:2011-10-04 20:56:00

标签: c# generics

我有一个util类(C#),我有一个静态方法,它接受某种类型的对象并调出一个Web服务来获取更多数据。我想支持其他对象类型并且不复制代码,即添加多个类似的方法,我认为通用路由是最好的。

例如,假设我有:

public static void GetData(Building building)
{
    var webClient = new WebClient();
    var wrapper = new WrapperClass(building);

    if (building.Distance.HasValue)
    {
        structure = new Structure((decimal)building.Length.Value, (decimal)building.Height.Value);
    }

    ... // and so on ...

而不是像这样创建另一种方法:

public static void GetDataForBridge(Bridge bridge)
{
    var webClient = new WebClient();
    var wrapper = new WrapperClass(bridge);

    if (bridge.Distance.HasValue)
    {
        structure = new Structure((decimal)bridge.Length.Value, (decimal)bridge.Height.Value);
    }

    // ...

我不知道如何使用Generics这样做。有人可以给我一些提示或建议吗?

3 个答案:

答案 0 :(得分:3)

在您的情况下,为什么不使用更简单的Building接口替换函数声明中的IHaveDistanceLengthAndHeight?这样你根本不需要泛型。

interface IHaveDistanceLengthAndHeight
{
    DistanceType Distance { get; }
    DistanceType Height   { get; }
    DistanceType Length   { get; }
}

class Building : IHaveDistanceLengthAndHeight
{
    ...

答案 1 :(得分:2)

听起来你可能应该使用共享接口而不是泛型。定义一个包含Distance属性和Length,Height等内容的接口;让你的桥和Building实现它,然后定义一个GetData()方法,它接受共享接口的实例。

public static viod GetData(IHasDimensions thing)
{
    var webClient = new WebClient();
    var wrapper = new WrapperClass(thing);

    if (thing.Distance.HasValue)
    {
        structure = new Structure((decimal)thing.Length.Value, (decimal)thing.Height.Value);
    }
    ...
}

答案 2 :(得分:1)

在这种情况下,Bridge和Building必须实现相同的接口,比如IObjectWithHeightAndWidth。然后,您可以将此接口指定为泛型方法的类型参数的约束。

(或者,代替公共接口,类可以共享一个公共基类。)

正如其他海报所指出的那样,你可能根本不需要仿制药。如果您随后需要将对象的强类型引用作为BridgeBuilding,则只需要泛型 - 例如,如果您需要在方法中调用另一个泛型方法,我们就是讨论