具有不同返回类型的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);
感谢所有的回复!
尝试使用泛型很好,但是泛型并不是万能的!
在这种情况下,我想知道与非泛型相比,您将节省多少代码:
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()
等。