具有不同返回类型的c#泛型接口

本文关键字:泛型接口 返回类型 | 更新日期: 2023-09-27 18:12:05

我有一个可以以多种格式返回数据的webservice。例如json和xml。我正在针对这个web服务构建一个简单的c# api,我希望这些方法能够从json,原始json或原始xml返回完全序列化的对象。例如:

List<Order> GetOrders(int customerId)
string GetOrders(int customerId)
XMLDocument GetOrders(customerId)
Customer GetCustomer(int customerId)
string GetCustomer(int customerId)
XMLDocument GetCustomer(int customerId)

我有一个关于做一个流畅的api的想法,你会调用SetFormat()方法,然后为上述方法返回一个公共接口。但是我被这个接口看起来像什么卡住了,因为返回序列化对象的实现返回不同类型的对象。

另一个更简单的解决方案是使用返回序列化对象的方法,然后添加out参数,如下所示:

List<Order> GetOrders(int customerId, out string data)

但我认为这不是一个很好的解决方案....

我更喜欢Sjoerd建议的非通用解决方案,我把问题弄得太复杂了。这是我最后做的:

public class ServiceEntity {
    List<Order> GetOrders(int customerId)....
}    
public class ServiceJson {
    string GetOrders(int customerId)....
}
public class ServiceXml {
    XmlDocument GetOrders(int customerId)....
}

然后是一个像这样的流畅服务类:

public class Service : IService {
    ....
    public AsJson() { return new ServiceJson(); }
    public AsEntity() { return new ServiceEntity(); }
    public AsXml() { return new ServiceXml(); }
}

像这样使用:

string json = Service.New().AsJson().GetCategories(1);
List<Order> = Service.New().AsEntity().GetCategories(1);

感谢所有的回复!

具有不同返回类型的c#泛型接口

尝试使用泛型很好,但是泛型并不是万能的!

在这种情况下,我想知道与非泛型相比,您将节省多少代码:

List<Order> GetOrdersAsList(int customerId)
string GetOrdersAsString(int customerId)
XMLDocument GetOrdersAsXml(customerId)

我打赌几乎没有!

如果您决定使用非泛型方法,很可能最终会在内部显示为:

List<Order> GetOrders(int customerId)
string OrdersToString(List<Order> orders)
XMLDocument OrdersToXml(List<Order> orders)

然后后两个方法可以移动到单独的类中,导致您的GetOrders()与格式解耦。

在我看来,这是一种比在这种情况下使用泛型更好、更干净的方法!

UPDATE:不要误解我的意思,我喜欢泛型,在很多情况下,它们使代码更具可读性。其他几个答案非常有趣,因为它们展示了实现这一目标的技术。所以我建议大家研究一下它们:它们在其他情况下可能会很有用。但是在这种情况下,目前提出的每个解决方案都有一个实际的缺点。这就是为什么我建议在这种情况下使用非泛型。

您也可以看看使用隐式操作符返回预期的数据。

例如:

public class OrderThingy 
{
    public static implicit operator List<Order>(OrderThingy orderthingy)
    {
        // Use CustomerId to get the data
        return new List<Order>();
    }
    public static implicit operator string(OrderThingy orderthingy)
    {
        // Use CustomerId to get the data
        return "string representation";
    }
    public static implicit operator XDocument(OrderThingy orderthingy)
    {
        // Use CustomerId to get the data
        return new XDocument();
    }
    private int CustomerId { get; set; }
    public OrderThingy GetOrders(int customerId)
    {
        CustomerId = customerId;
        return this;
    }
}

你可以这样使用:

XDocument doc = new OrderThingy().GetOrders(1);
List<Order> orders = new OrderThingy().GetOrders(2);
string stringorders = new OrderThingy().GetOrders(2);

创建一个泛型返回类

public class FormattedClass<T>
{
    List<T> ItemList { get; set; }
    string Json { get; set; }
    XmlDocument Document { get; set; }
}
public FormattedClass<T> GetItems<T>(long primaryKey)

方法呢

private class WebService
{
    public T GetOrders<T>(int customerId)
    {
        if (typeof(T) == typeof(List<Order>))
        {
            return new List<Order>();
        }
        if (typeof(T) == typeof(string))
        {
            return "42";
        }
    }
}

和取决于您在调用时提供的类型,如:

var webService = new WebService();
var a = webService.GetOrders<List<Order>>();
var b = webService.GetOrders<string>();

返回期望的值

泛型呢?

T GetOrders<T>(int customerID)

可以将不同的返回类型封装成一个公共类型:

CustomerResult GetCustomer(int customerId)

,

CustomerResults有:

Get/SetFormat()
Get/SetCustomer()
Get/SetXmlDoc()
Get/SetString()

等。